继承自泛型类型的数组

时间:2015-07-13 10:23:23

标签: c# generics inheritance

用于演示问题的代码:

static void Main(string[] args)
{
    var a = new A();
    var b = new B();
    Base<>[] all = new Base<>[] { a, b }; // doesn't work
}

class Base<T>
{
    public string Caption { get { return typeof(T).ToString(); } }
}

class A : Base<A> { }
class B : Base<B> { }

也许我走错了方向。想法是将Caption移动到基类(Base变为通用)。非通用版本没有问题:

var all = new Base[] { a, b }; // no problems for as long as Base is not generic

3 个答案:

答案 0 :(得分:2)

C#中没有Type<?> - 总是必须指定具体的泛型类型。

解决此问题的唯一方法是使Base<T>继承非泛型基类,或实现非泛型接口。然后,您可以将其用作数组的类型。

修改

在您的情况下,这非常简单,因为您想要的接口部分不包含泛型类型参数。所以你可以简单地做到:

public abstract class Superbase
{
  public abstract string Caption { get; }
}

public class Base<T>: Superbase
{
  public override string Caption { get { return typeof(T).Name; } }
}

或者,使用界面:

public interface IBase
{
  string Caption { get; }
}

public class Base<T>: IBase
{
  public string Caption { get { return typeof(T).Name; } }
}

您的数组将分别为Superbase[]IBase[]。在这两种情况下,你都可以看到我实际上并没有提供一个实现 - 从某种意义上说,这两个声明都是“抽象的”。

一般来说,我试图将非泛型内容保存在非泛型基类中,而不是将其填充到派生泛型类中。它感觉更干净:))

答案 1 :(得分:1)

基于@Luaan ideea,这是一个实现:

class Program
{
    static void Main(string[] args)
    {
        var a = new A();
        var b = new B();

        var arr = new Base[] { a, b};

        foreach (var obj in arr)
            Console.WriteLine(obj.Caption);

        Console.ReadKey();
    }
}

public class Base<T> : Base
{
    public override string Caption
    {
        get { return typeof (T).ToString(); }
    }
}

public class A : Base<A> { }

public class B : Base<B> { }

public abstract class Base
{
    public abstract string Caption { get; }
}

答案 2 :(得分:1)

不要尝试使用继承(这将导致更多问题),而是使用扩展方法:

public interface IClassAORClassB {}

class A : IClassAORClassB { }
class B : IClassAORClassB { }

public static class Captions
{
    public static string Caption<T>(this T obj) where T : IClassAORClassB
    {
        return obj.GetType().ToString();
    }
}

static void Main(string[] args)
{
    var a = new A();
    var b = new B();
    var all = new IClassAORClassB[] { a, b }; // works just fine
    Console.WriteLine(all[0].Caption()); // prints A
    Console.WriteLine(all[1].Caption()); // prints B
}