在C#中将泛型作为泛型类型参数传递

5

我在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个回答

2

我认为这里没有问题,只需向您的Owner类添加另一个通用参数:

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

1
也许你应该添加另一个类型参数:
class CollectionOwner<TGenericCollection, T2>
   where TGenericCollection : IGenericCollection<T2>
   where T2 : class
{
    protected TGenericCollection theCollection = default(TGenericCollection);
}

这符合您的需求吗?

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());
    }
}

0

使用第二个泛型参数肯定是一个选项,我已经想要使用它了,但这又怎么样呢?

    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);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接