【问题标题】:Cast object to generic interface将对象转换为通用接口
【发布时间】:2016-08-02 01:34:05
【问题描述】:

我有以下课程:

class MyObject { }
class MyObject2 { }

interface Parent<T>
{
    void DoSomething(T myObj);
}

class Child1 : Parent<MyObject1>
{
    public void DoSomething(MyObject1 myObj) { }
}

class Child2 : Parent<MyObject2>
{
    public void DoSomething(MyObject2 myObj) { }
}

我想创建一个返回父级的工厂方法,但出现以下转换错误

无法将类型“Child1”隐式转换为“Parent”。存在显式转换(您是否缺少演员表?)

static Parent<object> Factory()
    {
        return new Child1();
    }

有什么解决方法吗?

【问题讨论】:

  • but I get a casting error when I try to cast from Child1 to Parent 那么错误是什么..如果您不发布返回的相关错误,我们应该如何知道..?
  • Parent&lt;object&gt; != Parent&lt;MyObject1&gt;。如果您想在非通用上下文中使用Parent&lt;T&gt;,您将不得不create some interfaces。 (即类似于List&lt;T&gt; 如何实现非泛型IList
  • 如果客户不知道T是什么,应该如何使用返回的对象?
  • 您在这里尝试的是协方差。您只能使用接口来做到这一点。并且只有在类型仅用于输出时才应该这样做(而不是用于输入的 T 的情况)。但更重要的是,转换为 object 完全违背了泛型的目的,您应该重新考虑您的设计。

标签: c# .net c#-4.0 casting


【解决方案1】:

你所要求的是不可能的。将Parent&lt;MyObject1&gt; 称为Parent&lt;object&gt; 是没有意义的。如果您有string,则不能将其传递给签名为DoSomething(MyObject1) 的方法。你需要找到另一种方法来做你想做的事情。

【讨论】:

    【解决方案2】:

    我没有对此进行全面测试,因此可能会出现一些错误,但据我所知,您可以实现这一点,虽然有点草率,但请创建如下界面:

    public interface Parent
    {
        void DoSomething(object myObj);
    }
    

    还有一个抽象类

    public abstract class BaseParent<T> : Parent<T>, Parent
    {
        public abstract void DoSomething(T myObj);
    
        public void DoSomething(object myObj)
        {
            T obj = myObj as T;
            if (obj != null)
            {
                DoSomething(obj);
                return;
            }
    
            // Do something to handle null values, unexpected values
        }
    }
    

    修改 Child1 和 Child2 以实现抽象类。即:

    class Child1 : BaseParent<MyObject1>
    

    您应该能够将 Child1 或 Child2 转换为“Parent”。

    请注意,当 myObj 是 T 类型的值为 null 的值时,这不会处理这种情况,因此如果您需要接受 null 值,则需要做更多的事情。

    (如果你真的应该首先这样做,如果你传递一个不正确类型的对象......应该发生什么?)

    【讨论】:

      【解决方案3】:

      这很有趣,混合了泛型和子类。但在我看来,你不需要两个子类,因为它们实际上是同一个类,只是泛型参数不同。

      如果你写

      Public static Parent<MyObject1> Factory()
      {
         Return new Child1();
      }
      

      然后错误就消失了。本质上意味着返回类型应该是具体类型,因为工厂方法本身是非泛型的。

      所以你需要把工厂方法变成通用的,像这样:

      Public static Parent<T> Factory<T>() { return (Parent<T>)new Child1(); }
      

      您实际上是在尝试实现抽象工厂,抽象工厂有两个用于创建对象的参数,在您的情况下,一个是泛型​​类型,另一个是工厂方法创建对象所基于的参数。所以我建议看看抽象工厂设计模式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-16
        • 1970-01-01
        • 1970-01-01
        • 2021-07-24
        • 1970-01-01
        • 2019-05-08
        • 2017-10-09
        相关资源
        最近更新 更多