在C#中传递泛型作为泛型类型参数
问题描述:
我在C#中泛型做了一点实验,并且遇到了一个问题,我想通过泛型类型作为带有约束的类型参数来实现泛型类型的接口不知道。在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的限制。但是,这样做的正确方法是什么?
答
也许你应该另一种类型的参数:
class CollectionOwner<TGenericCollection, T2>
where TGenericCollection : IGenericCollection<T2>
where T2 : class
{
protected TGenericCollection theCollection = default(TGenericCollection);
}
这是否会适合你需要什么?
答
我不认为这里有一个问题,只是增加一个泛型参数到你的主阶级:
class CollectionOwner<T,TGenericCollection>
where TGenericCollection : IGenericCollection<T>
{
protected TGenericCollection theCollection = default(TGenericCollection);
}
答
您可以在第二个泛型参数添加到实现类。下面的静态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());
}
}
答
使用第二泛型参数是一个选项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);
}