我在基类中有一个类层次结构和一个静态方法,所以子类也有这个静态方法。我很乐意定义像
这样的静态方法public static IEnumerable<T> GetList<T>()
where T : BaseClass, new()
{
return new List<T>() { ... };
}
所以我可以打电话给
var list = ChildClass.GetList();
,列表为IEnumerable<ChildClass>
。但是:我不知道如何告诉编译器推断泛型类型是我调用的类的类型,所以这种用法产生错误,我必须纠正它以某种方式冗余
var list = ChildClass.GetList<ChildClass>();
我可以使用扩展方法(它们有this
参数,允许编译器捕获),但我希望在没有实例化ChildClass
的情况下执行此操作。
有没有办法在不重复的情况下完成此任务?
答案 0 :(得分:2)
你不能让编译器推断你调用的类,因为从技术上讲,你总是从定义方法的类调用。
允许您使用派生类名称的编译器只是一种便利。
答案 1 :(得分:1)
如果你可以忍受丑陋的黑客攻击,你可以使BaseClass
本身是通用的,并将子类'类型作为参数传递给泛型参数,例如:
class BaseClass<T> where T : BaseClass<T>, new()
{
public static IEnumerable<T> GetList()
{
return new List<T>() { new T() }; // whatever
}
}
class Child : BaseClass<Child>
{
}
class Child2 : BaseClass<Child2>
{
}
现在Child.GetList()
返回IEnumerable<Child>
,Child2.GetList()
返回IEnumerable<Child2>
。
答案 2 :(得分:1)
如果您想知道编译器无法解析类型的原因,请继续阅读:
首先,静态方法绑定到类型而不是对象。所以这里不能有任何多态行为。所以你有一个子,基类层次结构的事实在这里并不重要,因为这些方法被绑定到两个完全不同的实体。
真正的问题在于C#编译器的类型推断功能。您必须向编译器提供有关类型T
的信息。否则它无法推断它。
您无法在左侧提供此信息,因为C#类型推断从右到左工作。换句话说:
var ints = new {};
完全没问题。因为右侧的类型是匿名方法,并且ints被解析为一个。但是:
int[] ints = new [] {};
不行。编译器抱怨“没有找到隐式类型数组的最佳类型”。换句话说,编译器不能使用左侧的信息来确定右侧应该是什么类型。
在你的问题中
var list = ChildClass.GetList();
不向编译器提供有关T是什么的任何信息!即使你有类型而不是var也没有什么区别。