将实现替换为类型T的参数化类的T [英] Substituting implementations into the T of a parameterized class of type T

查看:134
本文介绍了将实现替换为类型T的参数化类的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆