C# 未定义的泛型类列表
本文关键字:列表 泛型类 未定义 | 更新日期: 2023-09-27 18:35:59
我有一个这样的类:
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 差异无效:类型参数"TOut"在"UI"上必须始终有效。Forms.SearchTool.Visualization.IViz.SelectedValues'."TOut"是协变的。 D:''projects''living''clients''NetClient''UI''Forms''SearchTool''Visualization''IViz.cs 8 42 UI
可以通过
添加接口并在类型参数上使用泛型修饰符out
来实现此行为,使其成为协变。
从文档中,输出(泛型修饰符):
对于泛型类型参数,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);
不,你不能这样做,但你可以定义一个只有一个泛型类型的公共接口:
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());