在泛型类中使用抽象类的静态属性,该类在抽象类的子类上起作用

Aad*_*mia 0 c# generics static

我对以下代码有疑问:

abstract class a
{
    public static string x;
}



class b<c> where c : a
{
    public void f()
    {
        c.x=10;
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码无法编译.我在语句cx = 10时收到错误; .问题使它看起来好像条件where c:a根本没有任何影响.有人可以解释为什么这是一个错误?是不是所有的孩子都将x作为静态成员共享?有没有办法解决这个问题?

我想要实现的是:我有一个a的子类,其所有对象共享一个公共属性,并且必须通过泛型类b中的f()设置此属性.如果我用ax = 10替换有问题的陈述,这样可以吗?如果不是,斧头如何与cx(或hx,其中h是a的子类)不同?

dtb*_*dtb 8

静态成员不是继承的,尽管通过派生类型访问静态成员是令人困惑的.例如,在以下代码中

class P
{
    public static string X;
}

class Q : P { }

class R : P { }
Run Code Online (Sandbox Code Playgroud)

您可以访问P.X通过P.XQ.XR.X,但它仍然是相同的字段:

P.X = "Hello";
Q.X = "World";
Console.WriteLine(R.X);  // prints "World"
Run Code Online (Sandbox Code Playgroud)

正如您所发现的,您无法使用泛型类型参数执行此操作.但是通过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"; }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果要将一些信息与类型(非实例)相关联,则可以使用泛型类定义使用类型参数化的静态字段:

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"
Run Code Online (Sandbox Code Playgroud)

那这个呢?

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

这与您在评论中描述的过程非常匹配.它应该工作,虽然我不是如何设计可配置的工作模型.