【问题标题】:How to cast a generic to the interface it implements when the type parameters on both implement a common interface in C#当两者上的类型参数在 C# 中实现公共接口时,如何将泛型转换为它实现的接口
【发布时间】:2017-12-21 16:33:25
【问题描述】:

考虑以下代码:

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&lt;Thing&gt;' and 'IContainer&lt;Thing&gt;'。

为什么需要一个从两者都继承的类型? Container&lt;T&gt; 没有实现IContainer&lt;IThing&gt; 吗?由于Thing 实现了IThing,并且Container&lt;T&gt; 中的T 保证实现IThing,看来我应该能够执行此转换。

【问题讨论】:

  • Container&lt;Thing&gt; 实现 IContainer&lt;IThing&gt; 而不是 IContainer&lt;Thing&gt;。
  • @hvd 什么,现在你要我真正注意?!天啊,人们问了很多。哎呀!

标签: c# generics interface casting


【解决方案1】:

Container&lt;T&gt; 没有实现IContainer&lt;IThing&gt;?

确实如此。

由于Thing 实现了IThing,并且Container&lt;T&gt; 中的T 保证实现IThing,看来我应该能够执行此转换。

out 正好相反。 out 表示如果类型实现了IContainer&lt;Thing&gt;,它也会自动实现IContainer&lt;IThing&gt;。反之亦然。

之所以称为out,是因为它可以返回一些东西。例如,您可能有

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

现在,IContainer&lt;Apple&gt; 将自动实现 IContainer&lt;Fruit&gt;,IContainer&lt;Banana&gt; 也将自动实现 IContainer&lt;Fruit&gt;。这行得通,因为返回Apple 的东西可以解释为返回Fruit。但是如果你只知道它返回一个Fruit,你不知道那个Fruit是不是一个Apple。

in 按您的要求工作。例如,您可能有

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

现在,IContainer&lt;Apple&gt;不会自动实现IContainer&lt;Fruit&gt;。那是因为需要Apple 的东西不能接受任意的Fruits。但是只需要Fruit的东西确实接受所有Apples。

【讨论】:

  • 谢谢。这是帮助我理解的关键,“......需要一个苹果的东西不能接受任意的水果。但只需要一个水果的东西确实接受所有的苹果。”
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-16
  • 2020-02-19
相关资源
最近更新 更多