class Bar
{
static public Bar Instance { get { return null; /*return instance*/ } }
}
private void Foo<T>() where T : Bar
{
T getInstace = T.Instance;
}
这是错误,但需要获取实例。
这有解决方案吗?
感谢
++
class Bar<T>
{
static public T Instance { get { return default(T); /*return instance*/ } }
}
class BarChild : Bar<BarChild>
{
public void Func(){}
}
private T Foo<T>() where T : Bar<T>
{
return T.Instance;
}
private void Example()
{
Foo<BarChild>().Func();
}
我想这样做,你知道。 但是,“T.Instance”是错误的..
答案 0 :(得分:0)
我认为这归结为对static
关键字的基本误解。它不是跨实例共享成员的机制,它是一种通知编译器它可以静态分配成员的方法,即不考虑程序在运行时的动态行为。
请注意,您无法成为static
成员virtual
,这意味着您无法在子类中覆盖它。由于子类化是一个静态过程,因此您可以引用父类的静态成员,就像它们被继承一样,因为编译器可以确定成员的定义位置。
即使您所描述的内容在语法上是合法的,T.Instance
也无法引用Bar.Instance
以外的任何内容。
答案 1 :(得分:0)
你实际上已经接近做你想做的事了。有些人可能认为这是滥用类型系统。我认为这是语言的弱点。您要解决的问题是您要访问泛型类的静态成员,该类的类型是类的类型,而不是硬编码类型。 可能。
class Base<T> where T : Base<T> {
public static T SomeMethod() { ... }
}
class Derived : Base<Derived> {
}
public void Main() {
Derived d = Derived.SomeMethod(); // correctly returns an object of type Derived, even though method is defined in base class
}
这是来自C ++的CRTP的变体。
所以这不是真正的虚拟或动态调度。使用静态函数获得此行为的唯一原因是泛型。这些类型在编译时都是已知的。它在类层次结构中仍然有用,在这种层次结构中,您希望派生类型能够使用基类型方法,就好像它们是派生类型的方法一样。或者,换句话说,您可以在基类中创建在派生类中工作的模板化方法,就像在那里声明它们一样。您可能想要使用它的一个地方是Clone()
方法,它返回正确的类型。您可以在基类中将其声明为public abstract T Clone()
,并且它在派生类中具有正确的返回类型。
编辑:更新代码以执行OP想要的所有内容:
public class Base<T>
where T : Base<T>, new() {
public static T Instance {
get {
return new T();
}
}
}
public class Derived : Base<Derived> {
public void SomeFunc() {
Console.WriteLine("SomeFunc()");
}
}
// in other code
private T Foo<T>() where T : Base<T>, new() {
// note that we can't just use T directly here, but that's okay, because we know that T is always going to be at least a Base<T>
return Base<T>.Instance;
}
private void Example() {
// the type of Base<Derived>.Instance is Derived, so you can call Func() on it
Base<Derived>.Instance.SomeFunc();
// can also do this:
Foo<Derived>().SomeFunc();
}