将实现替换为类型T的参数化类的T [英] Substituting implementations into the T of a parameterized class of type T
问题描述
说我有一个类似的设置
public interface IMyInterface { }
public class MyImplementation : IMyInterface { }
public class MyClass<T> where T : IMyInterface { }
我发现我不能做这样的替换
I figured out that I can't do a substitution like
var list = new List<MyClass<IMyInterface>>()
{
new MyClass<MyImplementation>()
}
我会收到错误消息
无法从
MyClass< MyImplementation>
转换为MyClass< IMyInterface>
这是否意味着我要尝试的是代码气味?
Does that mean what I'm trying to do is code smell?
推荐答案
不允许这样做,因为 List< T>
中的 T
是不变的.这是一个示例,它将说明:
It does not allow that because the T
in List<T>
is invariant. Here is an example which will explain:
public interface IFruit
{
string Name { get; set; }
}
public class Apple : IFruit
{
public string Name { get; set; }
public string Color { get; set; }
}
public class Orange : IFruit
{
public string Name { get; set; }
}
让我们在列表中添加一些水果:
Let's add some fruits to a list:
var fruits = new List<IFruit>();
fruits.Add(new Apple());
fruits.Add(new Orange());
稍后在代码中,您不知道添加了什么,然后执行以下操作:
Later in the code, you have no idea what was added and you do this:
Orange orange = fruits[0];
现在不会编译,但也没有意义,因为每个 IFruit
都不是 Apple
或 Orange
.
Now that will not compile but it also does not make sense because every IFruit
is not an Apple
or an Orange
.
如果编译器允许怎么办?
例如,如果编译器允许您尝试尝试的操作,例如:
If, for instance let's say, what you are trying was allowed by the compiler, like this:
// does not compile but let's say it did
List<Apple> fruits = new List<IFruit>();
然后,如果编译器允许这样做,它也应该允许这样做,因为它们都实现了 IFruit
:
Then if the compiler allowed that, it should also allow this since they both implement IFruit
:
fruits.Add(new Apple());
fruits.Add(new Orange());
然后在代码中的某个地方执行此操作(因为它是一个苹果列表):
then later on somewhere in code you do this (since it is a list of apples):
foreach (var thisFruit in fruits)
{
Console.WriteLine(thisFruit.Color)
}
崩溃!编译器一开始并没有阻止您,此时您正在查看代码,它显示 List< Apple>
,并且您写了代码并全部编译.在运行时,哦废话,没有 Color
属性,因为它是 Orange
.
Crash!! The compiler did not stop you at the beginning and at this point you are looking at the code and it says List<Apple>
, and you wrote code and all compiled. At runtime, oh crap, there is no Color
property because it is an Orange
.
这就是为什么不允许这样做的原因.
This is why it is not allowed.
这篇关于将实现替换为类型T的参数化类的T的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!