我有以下概念模型:
public interface IFoo<out T> { T Data { get; } } public struct Foo<T> : IFoo<T> { public Foo(T data) : this() { Data = data; } public T Data { get; private set; } } public class FooService<T> { ... public Foo<T> Get(string id) { ... } }
然后我尝试以一种概念上等同于此的方式使用它:
// Create and register a few FooService instances ServiceLocator.Register(new FooService<DateTime>(),"someServiceId"); ServiceLocator.Register(new FooService<double?>(),"anotherServiceId"); // Retrieve a particular FooService instance and call the Get method var fooService = (FooService<object>)ServiceLocator.Get("someServiceId"); var foo = fooService.Get("someFooId");
我想在FooService实例上使用Get()方法 – 无论选择的FooService实例返回什么类型.但是,此代码导致以下异常:
Unable to cast object of type ‘WindowsFormsApplication7.FooService`1[System.DateTime]’ to type ‘WindowsFormsApplication7.FooService`1[System.Object]’.
任何关于如何解决这个问题的建议都会受到高度赞赏.
你可能会争辩,为什么我首先制作了FooService泛型.但是,这样做是为了在类型安全的环境中确保类型安全.但是,在这种特殊情况下,FooService应该在Web API控制器中用于服务各种类型的Foo.无论T的类型如何,它都应返回T的Foo响应.
解决方法
我想你已经给出了正确答案:
FooService接口<加倍>永远不能被转换为FooService< object>,和
FooService接口< DateTime的>永远不能被转换为FooService< object>.
使用协方差或逆变不会改变这一点.页面https://msdn.microsoft.com/en-us/library/dd997386.aspx声明:值类型也不支持方差.既然加倍?和DateTime是值类型,这永远不会工作.