简体   繁体   English

当两种类型的参数都在C#中实现一个通用接口时,如何将泛型转换为它实现的接口

[英]How to cast a generic to the interface it implements when the type parameters on both implement a common interface in C#

Consider the following code: 考虑以下代码:

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;
  }
}

On this line: 在这行上:

var abstractContainer = (IContainer<Thing>) concreteContainer;

You get the following runtime error: InvalidCastException: Unable to cast object of type 'CastTest.Container`1[CastTest.Thing]' to type CastTest.IContainer`1[CastTest.Thing]'. 您会收到以下运行时错误: InvalidCastException: Unable to cast object of type 'CastTest.Container`1[CastTest.Thing]' to type CastTest.IContainer`1[CastTest.Thing]'.

Also if you have Resharper, it complains with, Suspecious cast: there is no type in the solution which is inherited from both 'Container<Thing>' and 'IContainer<Thing>' . 同样,如果您有Resharper,它Suspecious cast: there is no type in the solution which is inherited from both 'Container<Thing>' and 'IContainer<Thing>'

Why does there need to be a type that inherits from both? 为什么需要从两者继承的类型? Doesn't Container<T> implement IContainer<IThing> ? Container<T>实现IContainer<IThing>吗? Since Thing implements IThing , and T in Container<T> is guaranteed to implement IThing , it seems like I should be able to do this cast. 由于Thing实现IThingTContainer<T>是保证实现IThing ,好像我应该能够做到这一点演员。

Doesn't Container<T> implement IContainer<IThing> ? Container<T>实现IContainer<IThing>吗?

It does. 是的

Since Thing implements IThing , and T in Container<T> is guaranteed to implement IThing , it seems like I should be able to do this cast. 由于Thing实现IThingTContainer<T>是保证实现IThing ,好像我应该能够做到这一点演员。

out works the other way around. out工作周围的其他方法。 out means that if the type implements IContainer<Thing> , it automatically implements IContainer<IThing> as well. out表示如果该类型实现IContainer<Thing> ,则它也将自动实现IContainer<IThing> Not vice versa. 反之亦然。

It's called out because it can return something. 之所以叫out是因为它可以返回一些东西。 You might have for instance 你可能有

interface IThing<out T> {
    T Prop { get; }
}

Now, IContainer<Apple> would automatically implement IContainer<Fruit> , and IContainer<Banana> would also automatically implement IContainer<Fruit> . 现在, IContainer<Apple>将自动实现IContainer<Fruit> ,而IContainer<Banana>也将自动实现IContainer<Fruit> That works, because something which returns an Apple can be interpreted as returning a Fruit . 那行得通,因为返回Apple东西可以解释为返回Fruit But if you only know it returns a Fruit , you don't know whether that Fruit is an Apple . 但是如果你只知道它返回一个Fruit ,那么你便不知道该Fruit是否是Apple

in works the way you ask. in作品你问路。 You might have for instance 你可能有

interface IThing<in T> {
    void Act(T t);
}

Now, IContainer<Apple> does not automatically implement IContainer<Fruit> . 现在IContainer<Apple> 不会自动实现IContainer<Fruit> That's because something which requires an Apple won't be able to accept arbitrary Fruit s. 这是因为某些需要Apple将无法接受任意的Fruit But something which only requires a Fruit does accept all Apple s. 但是只需要一个Fruit东西就可以接受所有Apple的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM