简体   繁体   English

从泛型类型继承的数组

[英]Array of inherited from generic types

Code to demonstrate the problem: 演示问题的代码:

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> { }

Perhaps I went the wrong direction. 也许我走错了方向。 Idea was to move Caption into base class ( Base become generic). 想法是将Caption移入基类( Base变为通用)。 Non-generic version works without problems: 非通用版本可以正常工作:

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

There's no Type<?> in C# - you always have to specify a concrete generic type. C#中没有Type<?> -您总是必须指定一个具体的泛型类型。

The only way around this is to make Base<T> inherit a non-generic base-class, or implement a non-generic interface. 解决此问题的唯一方法是使Base<T>继承非通用基类,或实现非通用接口。 You could then use that as the type of the array. 然后,您可以将其用作数组的类型。

EDIT: 编辑:

In your case this is extremely simple, since the part of the interface you want doesn't include the generic type argument. 在您的情况下,这非常简单,因为所需的接口部分不包含泛型类型参数。 So you can simply do either: 因此,您可以简单地执行以下任一操作:

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

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

Or, using an interface: 或者,使用界面:

public interface IBase
{
  string Caption { get; }
}

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

Your array would then be Superbase[] or IBase[] , respectivelly. 然后,您的数组分别是Superbase[]IBase[] In both cases, you can see that I'm not actually providing an implementation - both the declarations are "abstract", in a sense. 在这两种情况下,您都可以看到我实际上没有提供实现 -从某种意义上说,两个声明都是“抽象的”。

In general, I'm trying to keep the non-generic stuff in a non-generic base class, rather than stuffing it in the derived generic classes. 通常,我试图将非泛型的东西保留在非泛型的基类中,而不是将其填充到派生的泛型类中。 It just feels more clean :) 感觉更干净:)

based on @Luaan ideea, here is an implementation: 基于@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; }
}

Instead of trying to use inheritance (which will lead to more problems down the line), use an extension method instead: 与其尝试使用继承(这将导致更多问题),不如使用继承方法:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM