当两个类型参数在C#中实现公共接口时,如何将泛型强制转换为它实现的接口
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当两个类型参数在C#中实现公共接口时,如何将泛型强制转换为它实现的接口相关的知识,希望对你有一定的参考价值。
请考虑以下代码:
public class Thing : IThing { }
public interface IThing {}
public interface IContainer<out T> where T : IThing { }
// This works
// public class Container<T> : IContainer<T> where T : IThing { }
// This doesn't work
public class Container<T> : IContainer<IThing> where T : IThing {}
internal class Program
{
private static void Main(string[] args)
{
var concreteContainer = new Container<Thing>();
var abstractContainer = (IContainer<Thing>) concreteContainer;
}
}
在这一行:
var abstractContainer = (IContainer<Thing>) concreteContainer;
您收到以下运行时错误:InvalidCastException: Unable to cast object of type 'CastTest.Container`1[CastTest.Thing]' to type CastTest.IContainer`1[CastTest.Thing]'.
如果你有Resharper,它会抱怨,Suspecious cast: there is no type in the solution which is inherited from both 'Container<Thing>' and 'IContainer<Thing>'
。
为什么需要一个继承自两者的类型? Container<T>
不实施IContainer<IThing>
?由于Thing
实施IThing
,并且T
中的Container<T>
保证实施IThing
,看起来我应该能够做到这一点。
Container<T>
不实施IContainer<IThing>
?
确实如此。
由于
Thing
实施IThing
,并且T
中的Container<T>
保证实施IThing
,看起来我应该能够做到这一点。
out
反过来工作。 out
意味着如果类型实现IContainer<Thing>
,它也会自动实现IContainer<IThing>
。反之亦然。
它被称为out
,因为它可以返回一些东西。例如,你可能有
interface IThing<out T> {
T Prop { get; }
}
现在,IContainer<Apple>
会自动实现IContainer<Fruit>
,而IContainer<Banana>
也会自动实现IContainer<Fruit>
。这是有效的,因为返回Apple
的东西可以被解释为返回Fruit
。但是,如果你只知道它返回Fruit
,你不知道Fruit
是否是Apple
。
in
以您要求的方式工作。例如,你可能有
interface IThing<in T> {
void Act(T t);
}
现在,IContainer<Apple>
不会自动实现IContainer<Fruit>
。这是因为需要Apple
的东西将无法接受任意的Fruit
s。但是只需要Fruit
的东西确实接受所有的Apple
s。
以上是关于当两个类型参数在C#中实现公共接口时,如何将泛型强制转换为它实现的接口的主要内容,如果未能解决你的问题,请参考以下文章