用于演示问题的代码:
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
答案 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
}