【问题标题】:Casting a generic object to an object with an interface of the generic type将泛型对象转换为具有泛型类型接口的对象
【发布时间】:2013-01-08 13:36:13
【问题描述】:

我有以下代码:

public class EntityFilter<T>
{}

public interface IEntity
{}

public class TestEntity : IEntity
{}

class Program
{
    static void Main(string[] args)
    {   
        var ef = new EntityFilter<TestEntity>();

        DoSomething((EntityFilter<IEntity>)ef); // <- casting fails
    }

    public static void DoSomething(EntityFilter<IEntity> someEntityFilter)
    {
    }
}

Visual Studio 说:

Cannot convert type 'ConsoleApplication1.EntityFilter<ConsoleApplication1.TestEntity>' to 'ConsoleApplication1.EntityFilter<ConsoleApplication1.IEntity>'

我无法将 DoSomething 方法转换为通用方法并接受 EntityFilter&lt;T&gt;,因为在我的应用程序中,在 DoSomething 调用时 T 的类型是未知的。稍后将在 DoSomething 内部使用反射确定类型。

如何在不使 DoSomething 方法泛型的情况下将 ef 变量传递给 DoSomething 方法?

【问题讨论】:

  • 为什么不能将ef 创建为EntityFilter&lt;IEntity&gt;
  • 为什么你不能让你的方法通用?这是正确的做法:method&lt;T&gt;(EntityFilter&lt;T&gt; ef) where T : IEntity
  • “不起作用”是什么意思?请提供有关您遇到的错误的信息。
  • @Martin,如果你这样做DoSomething&lt;T&gt;(EntityFilter&lt;T&gt; someEntity) where T : IEntity,你绝对不会失去任何东西。打电话时根本不需要指定TT 正确推断为TestEntity
  • @nawfal:哦,谢谢,你是对的。看来,这次推理可以解决问题,所以我不需要那种丑陋的强制转换,同时我也不必为 DoSomething 明确指定 T。

标签: c# generics interface type-conversion derived


【解决方案1】:

如果EntityFilter&lt;T&gt; 可以从接口派生并且该接口具有协变泛型参数,则您可以在方法中不使用泛型的情况下执行您所要求的操作。

注意IEntityFilter&lt;out T&gt; 定义中的“out”关键字。

public class Program
{
    static void Main(string[] args)
    {
        var ef = new EntityFilter<TestEntity>();

        DoSomething(ef);
    }

    public static void DoSomething(IEntityFilter<IEntity> someEntityFilter)
    {
    }
}

public interface IEntityFilter<out T>
{ }

public class EntityFilter<T> : IEntityFilter<T>
{ }

public interface IEntity
{ }

public class TestEntity : IEntity
{ }

【讨论】:

  • 仅供参考,.Net 4.0 中引入了泛型类型的协变和逆变,因此您需要 .Net 4.0 或更高版本才能使其工作。
  • 谢谢,这对我来说似乎是一个很好的解决方案,尤其是因为我的类包含许多其他非泛型方法。所以那个单一的 DoSomething 通用方法只是“不适合”。此外,我刚刚发现即使我没有为 T 指定“out”,以下演员表也能正常工作: var ef = (IEntityFilter)new EntityFilter();
  • ...但是我在转换时遇到运行时异常,所以无论如何都需要“out”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多