2016-02-24 57 views
0

我有一个类,如:C#未定义泛型类的列表?

class GClass<T1, T2> {} 

实现:

class CClass1<String, String> {} 
class CCLass2<String, Double> {} 

在我的C#代码,我需要像这样定义一个List<GClass<T1,?>对象。

可能吗?

通过另一方面,我曾与List<GClass<String, Object>>测试,但是我不能添加一个对象是这样的:

List<GClass<String, Object>> list = new List<GClass<String, Object>>(); 
CClass1 c1 = new CClass1(); 
list.Add(c1); 

编译转储我的编译错误。

编辑

我用它测试:

public interface IViz<T, TQuery, out TOut> 
{ 
    Configuration.IVizConfiguration<T> VizConfiguration { get; } 
    IList<TOut> SelectedValues { get; } 

    IEnumerable<TQuery> generate(IEnumerable<T> search); 
    Expression<Func<T, bool>> generateExpression(Object selectedVizValue); 
    IEnumerable<Expression<Func<T, bool>>> generateExpressions(IEnumerable<Object> selectedVizValues); 
} 

然而,编译器告诉我:

错误3无效方差:类型参数 '吹捧' 必须是在'UI.Forms.SearchTool.Visualization.IViz.SelectedValues'上不变。 'TOUT'是协变的。 d:\ PROJECTS \住\用户\ NetClient \ UI \表格\ SearchTool \可视\ IViz.cs 8 42 UI

+0

你能描述编译错误吗? – badikumar

+0

'CClass1 {}'CClass1'和'CClass2'是什么? – Ian

回答

5

您可以通过添加一个接口来完成此行为,使用通用的修改out你的类型参数,使之协调。

documentation, out (Generic Modifier)

对于一般类型参数,out关键字指定该类型参数是协变。您可以在通用接口和委托中使用out关键字。

协方差使您能够使用比通用参数指定的派生类型更多的派生类型。这允许实现变体接口的类的隐式转换以及隐式转换委托类型。协方差和反变量支持引用类型,但不支持值类型。

例子:

public interface GInterface<T1, out T2> {} 
public class GClass<T1, T2> : GInterface<T1, T2> {} 

用法:

List<GInterface<String, Object>> list = new List<GInterface<String, Object>>(); 
GClass<string, string> c1 = new GClass<string, string>(); 
list.Add(c1); 
+0

我测试了你的方法。我不知道为什么,但编译器告诉我一个错误。看看问题。谢谢! – Jordi

+0

由于'IList'不是协变的,你可能会发现这个错误,你可以将它改为IEnumerable,它是协变的。 –

4

不,你不能这样做,但你可以定义只具有一般类型的一个通用的接口:

interface IClass<T> { } 
class GClass<T1, T2> : IClass<T1> { } 

class CClass1 : GClass<string, object> { } 
class CClass2 : GClass<string, double> { } 

然后你可以创建一个通用接口列表:

List<IClass<String>> list = new List<IClass<String>>(); 
list.Add(new CClass1()); 
list.Add(new CClass2());