C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

List<T>を絞り込むジェネリックメソッドの書き方

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■84003 / inTopicNo.1)  List<T>を絞り込むジェネリックメソッドの書き方
  
□投稿者/ なと (1回)-(2017/05/08(Mon) 14:18:10)

分類:[C#] 

C# 2017でList<T>から、特定の派生クラス型で特定のプロパティに一致するアイテムのみを抽出するメソッドを作りたいと考えました。
派生クラスが大量に存在するため、調べていたらメソッドに<T>をつけてジェネリックにすれば型が指定出来るというところまでは分かったのですが、下記の箇所で詰まりました。どのように書いたら良いのでしょうか。

またLINQを使えばメソッドを自作しなくても1行で書けたりするのでしょうか。

よろしくお願い致します。

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        public static List<AAA> AllItems = new List<AAA>();

        static void Main(string[] args)
        {
            //テストデータ
            AllItems.Add(new AAA("aaa"));
            AllItems.Add(new BBB("bbb", 111));
            AllItems.Add(new BBB("b", 222));
            AllItems.Add(new BBB("bbb", 333));
            AllItems.Add(new CCC("ccc", 4.44));
            AllItems.Add(new CCC("c", 5.55));
            AllItems.Add(new CCC("ccc", 6.66));

            //BBBのみを抽出
            List<BBB> itemsBBB = GetItems<BBB>("bbb");

            //出力
            foreach (var item in itemsBBB)
            {
                Console.WriteLine(item.Name + " : " + item.Num);
            }
        }

        /// <summary>
        /// 特定の派生クラス型で特定の名前のアイテムのみを抽出
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<T> GetItems<T>(string name)
        {
            List<T> list = new List<T>();
            foreach (var item in AllItems)
            {
                if (item is T && item.Name == name)
                {
                    list.Add((T)item);  //←ここでキャスト不可のコンパイルエラーとなる。
                }
            }
            return list;
        }
    }

    public class AAA
    {
        public string Name { get; set; }
        public AAA(string name) { this.Name = name; }
    }

    public class BBB : AAA
    {
        public int Num { get; set; }
        public BBB(string name, int num) : base(name) { this.Num = num; }
    }

    public class CCC : AAA
    {
        public double Num { get; set; }
        public CCC(string name, double num) : base(name) { this.Num = num; }
    }

}

引用返信 編集キー/
■84004 / inTopicNo.2)  Re[1]: List<T>を絞り込むジェネリックメソッドの書き方
□投稿者/ Hongliang (542回)-(2017/05/08(Mon) 14:21:11)
2017/05/08(Mon) 14:28:22 編集(投稿者)
OfType<T>で。

foreach (var item in AllItems.OfType<BBB>()) {
    Console.WriteLine(item.Name + " : " + item.Num);
}

<追記>
あ、Nameによる絞り込みもあるのなら続けてWhereで
AllItems.OfType<BBB>().Where(_item => _item.Name == "BBB")

引用返信 編集キー/
■84005 / inTopicNo.3)  Re[2]: List<T>を絞り込むジェネリックメソッドの書き方
□投稿者/ PANG2 (177回)-(2017/05/08(Mon) 14:46:21)
ジェネリック型制約(where)で、

public static List<T> GetItems<T>(string name) where T : AAA

引用返信 編集キー/
■84006 / inTopicNo.4)  Re[2]: List<T>を絞り込むジェネリックメソッドの書き方
□投稿者/ ぶなっぷ (105回)-(2017/05/08(Mon) 14:53:32)
コンパイル通すだけなら、以下の通り、
  where T : AAA
の一行を足す。

public static List<T> GetItems<T>(string name)
  where T : AAA

引用返信 編集キー/
■84007 / inTopicNo.5)  Re[1]: List<T>を絞り込むジェネリックメソッドの書き方
□投稿者/ shu (1017回)-(2017/05/08(Mon) 14:55:11)
No84003 (なと さん) に返信
public static List<T> GetItems<T>(string name) where T : AAA
{
    var list = AllItems.OfType<T>().Where(_ => _.Name == name).ToList();
    return list;
}

引用返信 編集キー/
■84008 / inTopicNo.6)  Re[2]: List<T>を絞り込むジェネリックメソッドの書き方
□投稿者/ なと (2回)-(2017/05/08(Mon) 15:04:56)
以下の3点、大変勉強になりました。
・ジェネリック型制約(where)
・AllItems.OfType<BBB>()
・.Where(_item => _item.Name == "BBB")
皆様ありがとうございました!
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ