4

C# でジェネリックについて少し実験を行ったところ、型がわからないジェネリック インターフェイスを実装する制約付きの型パラメーターとしてジェネリック型を渡したいという問題がありました。

これが私の例です:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication3
{
    class Program
    {
        interface IGenericCollection<T>
        {
            IEnumerable<T> Items { get; set; }
        }

        abstract class GenericCollection<T> : IGenericCollection<T>
        {
            public IEnumerable<T> Items { get; set; }
        }

        //This class holds a generic collection but i have to ensure this class
        //implements my IGenericCollection interface. The problem here is that
        //i dont know which type TGenericCollection is using and so i am unable to
        //pass this information to the constraint. 

        class CollectionOwner<TGenericCollection>
           where TGenericCollection : IGenericCollection< dont know ... >
        {
            protected TGenericCollection theCollection = default(TGenericCollection);
        }

        static void Main(string[] args)
        {
        }
    }
}

ここでいくつかの投稿を読みましたが、C# と CLR の制限により不可能であるとのことでした。しかし、これを行う正しい方法は何でしょうか?

4

4 に答える 4

1

2 番目のジェネリック パラメーターを実装クラスに追加できます。以下の静的Exampleメソッドは、この例を示しています。

public interface ITest<T>
{
    T GetValue();
}

public class Test<T, U> where T : ITest<U>
{
    public U GetValue(T input)
    {
        return input.GetValue();
    }
}

public class Impl : ITest<string>
{
    public string GetValue()
    {
        return "yay!";
    }

    public static void Example()
    {
        Test<Impl, string> val = new Test<Impl,string>();
        string result = val.GetValue(new Impl());
    }
}
于 2013-03-08T19:02:42.963 に答える
1

おそらく、別の型パラメーターを使用する必要があります。

class CollectionOwner<TGenericCollection, T2>
   where TGenericCollection : IGenericCollection<T2>
   where T2 : class
{
    protected TGenericCollection theCollection = default(TGenericCollection);
}

このスーツは必要ですか?

于 2013-03-08T18:57:10.487 に答える
1

ここに問題はないと思います。Owner クラスに別のジェネリック パラメータを追加するだけです。

 class CollectionOwner<T,TGenericCollection>
           where TGenericCollection : IGenericCollection<T>
        {
            protected TGenericCollection theCollection = default(TGenericCollection);
        }
于 2013-03-08T18:57:25.263 に答える
0

Using a second generic parameter is an option 4 sure which i already wanted to use but what about this

    abstract class GenericCollection<T> : IGenericCollection<T>
    {
        public IEnumerable<T> Items { get; set; }
    }

    class ConcreteCollection : GenericCollection<string>
    {

    }

    static void Main(string[] args)
    {
       // will constraint fail here ?
       CollectionOwner<int,ConcreteCollection> o = new  CollectionOwner(int, ConcreteCollection);
    }
于 2013-03-08T19:45:40.523 に答える