我对以下代码有疑问:
abstract class a
{
public static string x;
}
class b<c> where c : a
{
public void f()
{
c.x=10;
}
}
此代码无法编译。我在语句c.x = 10时收到错误; 。问题使得看起来条件where c:a
根本没有任何影响。有人请解释为什么这是一个错误?是不是所有的孩子都将x作为静态成员共享?有没有办法解决这个问题?
我想要实现的是:我有一个a的子类,其所有对象共享一个公共属性,并且必须通过泛型类b中的f()设置此属性。如果我用a.x = 10替换有问题的陈述,这样可以吗?如果没有,a.x与c.x(或h.x,h是a的子类)有什么不同?
答案 0 :(得分:8)
静态成员不是继承的,尽管通过派生类型访问静态成员是令人困惑的。例如,在以下代码中
class P
{
public static string X;
}
class Q : P { }
class R : P { }
您可以通过P.X
或P.X
或Q.X
访问R.X
,但它仍然是相同的字段:
P.X = "Hello";
Q.X = "World";
Console.WriteLine(R.X); // prints "World"
正如您所发现的,您无法使用泛型类型参数执行此操作。但是通过类型参数访问X
并没有多大意义,因为您更改的是P.X
,您可以直接编写而不使用泛型类型参数。
我不确定你想要实现的目标。如果您有一个抽象类A
并希望从A
派生的所有类型实例都具有某个属性,则可以定义:
abstract class A
{
public abstract string X
{
get;
}
}
class A1 : A
{
public override string X
{
get { return "A1"; }
}
}
class A2 : A
{
public override string X
{
get { return "A2"; }
}
}
如果要将一些信息与类型(非实例)相关联,可以使用泛型类定义一个使用类型参数化的静态字段:
class Info<T>
{
public static string X;
}
Info<A1>.X = "Hello";
Info<A2>.X = "World";
Console.WriteLine(Info<A1>.X); // prints "Hello"
Console.WriteLine(Info<A2>.X); // prints "World"
这个怎么样?
abstract class Job
{
public abstract string ExePath
{
get;
}
public void Execute(string[] args)
{
Console.WriteLine("Executing {0}", this.ExePath);
}
}
abstract class Job<T> where T : Job<T>
{
public override string ExePath
{
get { return JobInfo<T>.ExePath; }
}
}
class ConcreteJob1 : Job<ConcreteJob1> { }
class ConcreteJob2 : Job<ConcreteJob1> { }
static class JobInfo<T> where T : Job<T>
{
public static string ExePath;
}
static class JobInfoInitializer
{
public static void InitializeExePaths()
{
JobInfo<ConcreteJob1>.ExePath = "calc.exe";
JobInfo<ConcreteJob2>.ExePath = "notepad.exe";
}
}
这与您在评论中描述的过程非常吻合。它应该工作,虽然我不是如何设计可配置的工作模型。
答案 1 :(得分:0)
如果您希望为每个子类使用不同的静态后备存储,但希望能够以多态方式从实例访问该状态,则可以执行以下操作:
abstract class A
{
public abstract string X { get; set; }
}
class D : A
{
private static string _x;
public override string X
{
get { return _x; }
set { _x = value; }
}
}
A的不同子类可以提供它们自己的X实现,包括使用后备静态存储,如果需要的话。请注意,这不一定是个好主意,因为这种棘手的全局状态(伪装成实例属性)可能会使您的代码难以理解和维护。
答案 2 :(得分:0)
这是一个错误,因为c
是generic type parameter,不是类型。静态成员只能通过类型访问。
如果我更换它,它会没用 a.x = 10时有问题的陈述?如果 不,a.x与c.x有什么不同(或者 h.x其中h是a)的子类?
您确实可以用a.x=10;
替换该语句。如您所见,这意味着b.x
,c.x
和d.x
也将等于10。