[英]Casting to a generic class with interface
更新了MarcinJuraszek的输入
我有一种感觉,我在这里碰到了一个共同/逆向差异问题,但我不确定我是否理解如何修复它。 我有一个这样的课:
public interface ISomeClass<TEnum, out S>
{
TEnum Dim { get; }
IEnumerable<S> Inc { get; }
}
public class SomeClass<TEnum, S> : ISomeClass<TEnum, S>
where TEnum : struct, IConvertible
where S : IMyInterface
{
public TEnum Dim { get; set; }
public IEnumerable<S> Inc { get; set; }
}
我有一个实现IMyInterface
的类
public class MyImplementation : IMyInterface
{
}
当然,我有一个带有SomeClass
属性的类:
public class MyContainer<TEnum> where TEnum : struct, IConvertible
{
public SomeClass<TEnum, IMyInterface> MyProp { get; set; }
}
现在我的问题是我无法将SomeClass<MyEnum, MyImplementation>
分配给MyProp
属性,因为我在运行时收到InvalidCastException
,抱怨它无法将SomeClass<MyEnum, MyImplementation>
InvalidCastException
为SomeClass<MyEnum, MyImplementation>
SomeClass<MyEnum, IMyInterface>
。
我该如何解决这个问题?
例如,这不编译:
var c = new MyContainer<MyEnum>();
c.MyProp = new SomeClass<MyEnum, MyImplementation>();
这是一个小点网小提琴
您可以通过使泛型类型参数不变(协变或逆变,取决于其成员)来使其工作。 但是,在C#中,您只能声明接口上不变的泛型参数,因此您必须声明另一个接口:
public interface ISomeClass<TEnum, in S>
{
}
public class SomeClass<TEnum, S> : ISomeClass<TEnum, IMyInterface>
where TEnum : struct, IConvertible
where S : IMyInterface
{
}
public class MyContainer<TEnum> where TEnum : struct, IConvertible
{
public ISomeClass<TEnum, IMyInterface> MyProp { get; set; }
}
这将使以下代码编译:
var container = new MyContainer<DayOfWeek>();
container.MyProp = new SomeClass<DayOfWeek, MyImplementation>();
另一种可能的解决方案是使用另一个接口,其中S
泛型类型参数不存在:
public interface ISomeClass<TEnum>
where TEnum: struct, IConvertible
{
}
public class SomeClass<TEnum, S> : ISomeClass<TEnum>
where TEnum : struct, IConvertible
where S : IMyInterface
{
}
public class MyContainer<TEnum> where TEnum : struct, IConvertible
{
public ISomeClass<TEnum> MyProp { get; set; }
}
奖金 - 为什么它不起作用:
让我们假设您的代码编译,只要T
实现IT
,您就可以将MyClass<T>
分配给MyClass<IT>
。 你可以有以下课程:
class MyClass<T>
{
public List<T> MyProp { get; set; }
}
并做
MyClass<IMyInterface> instance = new MyClass<MyInterfaceImplementation>();
使用该instance.MyProp
List<MyInterfaceImplementation>
将是List<MyInterfaceImplementation>
但您可以访问它,就像它是List<IMyInterface>
因此您可以尝试添加MyOtherInterfaceImplementation
元素,这会在运行时崩溃。 不好玩。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.