web-dev-qa-db-ja.com

汎用のIEnumerable <T>を返します

私はジェネリックとIEnumerable abitをいじっていますが、ちょっと行き詰まっています。私がやろうとしていることは次のとおりです:IEnumerable(?)を実装するコレクション型を返すメソッドが必要です(たとえば:List、Stack、Queue、...)

さらに、任意のデータ型の任意のコレクション型を返すことができるようにしたいです。だから私はこのメソッドがList<string>,だけでなくStack<int>だけでなくList<double>...などを返すことができるようにしたい.

 public IEnumerable<T> returnSomething() 
    {
        Stack<int> stackOfInts = new Stack<int>();
        List<string> listOfStrings = new List<string>();
        return stackOfInts;
    }

これは私が今まで試したことです。しかし、これは動作しません、私はこのエラーを受け取ります:

Cannot implicitly convert type 'System.Collections.Generic.Stack<int>' to 'System.Collections.Generic.IEnumerable<T>'. An explicit conversion exists (are you missing a cast?)

ただし、メソッドシグネチャのIEnumerable<T>IEnumerable<int>に置き換えると、int型のコレクションを返すことができます。しかしこれは、今ではListOfStringsを返すことができなくなったことを意味します。

提案やアイデアをいただければ幸いです:)

21
Thousand

メソッドに generic type parameter を追加する必要があります。

public IEnumerable<T> ReturnSomething<T>() 
{
    Stack<T> stackOfT = new Stack<T>();
    return stackOfT;
}

Typeパラメーターは、メソッド名の後、パラメーターの前に表示されます。複数の型パラメーターを持つメソッドを持つことも可能です。

メソッドを呼び出すときに、タイプを指定できます。

IEnumerable<int> myInts = ReturnSomething<int>();
29
Mark Byers

トリックはdeclare<T>正しいことです。汎用<T>を定義する場合、メソッドでそれに固執する必要があるため、IEnumerable<T>がある場合メソッドの他の場所では、<T>やその他のタイプではなく、<int>を使用する必要があります。

実際にseジェネリック型を使用する場合は、実際の型の代わりにジェネリック<T>を使用します。

サンプルを見る

class Foo<T>
{
    public IEnumerable<T> GetList()
    {
        return new List<T>();
    }

    public IEnumerable<T> GetStack()
    {
        return new Stack<T>();
    }
}

class Program
{
    static void Main(string[] args)
    {
        Foo<int> foo = new Foo<int>();
        IEnumerable<int> list = foo.GetList();
        IEnumerable<int> stack = foo.GetStack();

        Foo<string> foo1 = new Foo<string>();
        IEnumerable<string> list1 = foo1.GetList();
        IEnumerable<string> stack1 = foo1.GetStack();
    }
}
11
oleksii
public IEnumerable<T> returnSomething() 
{
    Stack<int> stackOfInts = new Stack<int>();
    return (IEnumerable<T>) stackOfInts;
}
3
burning_LEGION

Typeパラメーターは、呼び出し元がどこかで指定する必要があります。

ジェネリッククラスをインスタンス化する場合:

public class MyClass<T>
{
    public IEnumerable<T> returnSomething()
    {
        Stack<T> stackOfTs = new Stack<T>();
        List<T> listOfTs = new List<T>();
        return stackOfTs;
    }
}

var v = new MyClass<int>();
foreach(var item in v.returnSomething())
{
}

または、非ジェネリッククラスのジェネリックメソッドを呼び出す場合:

public class MyClass
{
    public IEnumerable<T> returnSomething<T>()
    {
        Stack<T> stackOfTs = new Stack<T>();
        List<T> listOfTs = new List<T>();
        return stackOfTs;
    } 
}


var v = new MyClass();
foreach(var item in v.returnSomething<int>())
{
}
2
Joe

はい、IEnumerable<T> to IEnumerable<dynamic>を変更すると、任意の型を返すことができます

このような:

public IEnumerable<dynamic> returnSomething() 
{
.....
0
HatSoft