C#未定义泛型类的列表?

时间:2016-02-24 15:11:18

标签: c# generics

我的课程如下:

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方差无效:类型参数&#39; TOut&#39;必须在&#39; UI.Forms.SearchTool.Visualization.IViz.SelectedValues&#39;上无条件有效。 &#39; TOUT&#39;是协变的。 D:\ projects \ living \ clients \ NetClient \ UI \ Forms \ SearchTool \ Visualization \ IViz.cs 8 42 UI

2 个答案:

答案 0 :(得分:5)

您可以通过添加接口并在类型参数上使用泛型修饰符out来实现此行为,从而使其协变。

来自documentation, out (Generic Modifier)

  

对于泛型类型参数,out关键字指定type参数是协变的。您可以在通用接口和委托中使用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);

答案 1 :(得分: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());