【问题标题】:inheritance with c# generic, while class type is inherited用c#泛型继承,而类类型是继承的
【发布时间】:2012-02-22 01:47:19
【问题描述】:

在 C# 中可以做到这样的事情吗?

假设我有这个:

public class T : U
{
 ...
}

我想要这个:

public class A<T> : B<U>
{
...
}

这样我就可以在我的代码中使用它:

B<U> x = new A<T>();

【问题讨论】:

    标签: c# generics inheritance


    【解决方案1】:

    你不能完全像你写的那样,但你可以这样做:

    public class A<T, U> : B<U> where T : U
    {
       ...
    }
    

    然后做

    B<U> x = new A<T, U>();
    

    【讨论】:

    • 他可以完全按照他写的那样拥有它,但这可能并不意味着他想要它。但如果他愿意,他可以将他输入的内容作为有效的 C#。 :)
    • 好吧,我写的不是我的意思:)
    【解决方案2】:

    该初始代码确实可以正常工作...尽管由于您使用的术语可能存在一些混淆...

    我相信你写的代码可以改写得更清楚如下:

    void Main()
    {
        B<Foobar> x = new A<Wibble>();
    
    }
    
    // Define other methods and classes here
    public class Foobar
    {
    }
    
    public class Wibble : Foobar
    {
    }
    
    public class B<U>
    {
    }
    
    public class A<T> : B<Foobar>
    {
    }
    

    要注意的关键是,有时您在泛型参数的上下文中使用 U,有时您将其用作具体类。

    上面的代码(就 LINQPad 编译成的 IL 而言)等价于:

    void Main()
    {
        B<U> x = new A<T>();
    
    }
    
    // Define other methods and classes here
    public class U
    {
    }
    
    public class T : U
    {
    }
    
    public class B<U>
    {
    }
    
    public class A<T> : B<U>
    {
    }
    

    只有最后两个类使用泛型参数,最后一个类没有将 U 定义为泛型参数,因此它将其视为具体类。很难说这是否是您想要的,因为您没有告诉我们您想要什么,只是向我们展示了一些代码。我想您可能想要@Roy Dictus 回答的两个通用参数解决方案,但您可能想要这个。很难说。 ;-)

    我应该注意,我将此答案部分归功于已删除的先前答案。该答案指出代码编译得很好,这启发了我测试实际代码。遗憾的是,由于答案被删除,我无法将灵感归功于相关人员。

    谢谢大家。克里斯这解决了我的问题,前提是我能够在下面的A&lt;T&gt; 的构造函数中调用T 的构造函数: public class A&lt;T&gt; : B&lt;Foobar&gt; { } 我该怎么做? – jambodev 1 分钟前

    在这种情况下,T 是一个泛型参数,所以你必须告诉编译器 T 绝对是可构造的。为此,您需要约束 T 以确保它具有构造函数。然后你应该能够随时创建它的新实例(例如T foo = new T();

    你当然不能像链接基类的构造函数那样调用构造函数,因为 A 不以任何方式从 T 派生,它只是在其泛型模式中使用 T 类型的对象。

    public class A<T> : B<Foobar> where T :new()
    {
        public T MyInstance {get; set;}
        public A()
        {
            MyInstance = new T();
        }
    }
    
    void Main()
    {
        B<Foobar> x = new A<Wibble>();
        Wibble y = ((A<Wibble>)x).MyInstance;
    }
    

    (此代码替换了我第一个代码块中的等效方法)

    请注意,y 是在 x 的构造函数中创建的 Wibble 类型的对象。另请注意,我需要在访问 x 之前强制转换它,因为 B&lt;Foobar&gt; 对泛型类型 Wibble 的使用一无所知。

    【讨论】:

    • 谢谢大家。克里斯这解决了我的问题,前提是我能够在下面的 A 的构造函数中调用 T 的构造函数: public class A : B { } 我该怎么做?
    【解决方案3】:

    不完全清楚你要做什么(类名没有帮助,我的大脑正在为 T 类苦苦挣扎)。 Roy Dictus 的回答是您想要的,还是 Chris 的回答是您想要的?我以与前者不同的方式解释了这个问题,就像这样

        public class MyBaseClass  {}
    
        public class MyClass : MyBaseClass {}
    
        interface IB<out T>{}
    
        public class B<T> : IB<T> { }
    
        public class A<T> : B<T>   {}
    
        static void Main(string[] args)
        {
            IB<MyBaseClass> myVar = new A<MyClass>();
        }
    

    关键是interfaces support covariance, classes do not

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-27
      • 2015-09-15
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多