假设我有List<IMyInterface>
...
我有三个实施IMyInterface
的课程:MyClass1
,MyClass2
和MyClass3
我有一个只读字典:
private static readonly Dictionary<Type, Type> DeclarationTypes = new Dictionary<Type, Type>
{
{ typeof(MyClass1), typeof(FunnyClass1) },
{ typeof(MyClass2), typeof(FunnyClass2) },
{ typeof(MyClass3), typeof(FunnyClass3) },
};
我有另一个界面IFunnyInteface<T> where T : IMyInterface
我有一个方法:
public static IFunnyInterface<T> ConvertToFunnyClass<T>(this T node) where T : IMyInterface
{
if (DeclarationTypes.ContainsKey(node.GetType())) {
IFunnyInterface<T> otherClassInstance = (FunnyInterface<T>) Activator.CreateInstance(DeclarationTypes[node.GetType()], node);
return otherClassInstance;
}
return null;
}
我正在尝试调用FunnyClasses的构造函数并将其作为参数插入myClass对象。我不想知道它是哪个对象:我只想用MyClass作为参数来实例化一些FunnyClass。
当我调用ConvertToFunnyClass时会发生什么,T
的类型为IMyInterface
,当我尝试将其强制转换为FunnyInterface<T>
时,它表示我无法转换FunnyClass1
例如,FunnyInterface<IMyInterface>
我目前的解决方法(不是一个漂亮的解决方法)是:
public static dynamic ConvertToFunnyClass<T>(this T node) where T : IMyInterface
{
if (DeclarationTypes.ContainsKey(node.GetType())) {
var otherClassInstance = (FunnyInterface<T>) Activator.CreateInstance(DeclarationTypes[node.GetType()], node);
return otherClassInstance;
}
return null;
}
我不喜欢它,因为返回类型是dynamic
,所以当我从其他地方访问它时,我不知道它是什么类型,我失去了intellisense和东西。我也不知道任何性能影响。
任何线索?
提前致谢!
解决
当我使用C#4.0时,我可以使用协方差(仅限输出位置)停止输出错误,因此我将IFunnyInterface
更改为
IFunnyInteface<out T> where T : IMyInterface
谢谢大家的回复。
答案 0 :(得分:1)
基本上,您的问题是您要将FunnyInterface<T>
转换为FunnyInterface<IMyInterface>
。正如已多次提到的(一个例子是here,更多信息here),这在大多数情况下都无效。仅在.NET 4中,当泛型类型是接口或委托,并且类型参数已显式声明为in
或out
的变体时,您是否可以执行此转换。
FunnyInterface
实际上是一个界面吗?
答案 1 :(得分:1)
thecoop答案指出你为什么不能这样做。
问题的清洁解决方案(除了使用动态)将是一个基本的非泛型接口:
public interface IFunnyInterfaceBase
{
}
public interface IFunnyInteface<T> : IFunnyInterfaceBase
where T : IMyInterface
{
}
您需要将您在该代码中使用的方法签名从IFunnyInteface移动到IFunnyInterfaceBase。
这样你就能写出这样的东西:
MyClass2 c2 = new MyClass2();
IFunnyInterfaceBase funnyInstance = c2.ConvertToFunnyClass();
你在代码中遇到的异常不是由于扩展方法签名本身(方法很好)..它是由你的左值类型(用于存储其返回的变量的类型)产生的值)!
显然此解决方案仅适用于您修改IFunnyInterface源代码的情况!