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

您可以将第二个泛型参数添加到实现类。下面的静态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

使用第二个通用参数是一个选项 4,确定我已经想使用它,但是这个呢

    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 回答