簡體   English   中英

在泛型類中使用抽象類的靜態屬性,該泛型類可用於抽象類的子類

[英]using static property of an abstract class inside a generic class that works on subclasses of the abstract class

我對以下代碼有疑問:

abstract class a
{
    public static string x;
}



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

此代碼無法編譯。 我在語句cx = 10時收到錯誤; 問題看起來好像where c:a的條件根本沒有任何作用,有人可以解釋為什么這是一個錯誤嗎? x由a的所有子元素共享為靜態成員是不正確的? 有沒有辦法解決這個問題?

我要實現的目標是:我有一個a的子類,所有這些對象都具有一個公共屬性,並且必須通過通用類b中的f()設置此屬性。 如果我將相關語句替換為ax = 10,可以嗎? 如果不是,ax與cx(或hx,其中h是a的子類)有什么不同?

盡管可以通過派生類型訪問靜態成員,但是可能會混淆靜態成員。 例如,在以下代碼中

class P
{
    public static string X;
}

class Q : P { }

class R : P { }

您可以通過PXQXRX訪問PX ,但仍是同一字段:

P.X = "Hello";
Q.X = "World";
Console.WriteLine(R.X);  // prints "World"

正如您所發現的,您不能使用泛型類型參數來做到這一點。 但是通過type參數訪問X並沒有多大意義,因為您所更改的只是PX ,而您直接編寫而沒有泛型type參數。


我不確定您要達到什么目標。 如果您有一個抽象類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";
    }
}

這與您在評論中描述的過程非常匹配。 它應該可以工作,盡管這不是我設計可配置Job模型的方式。

如果每個子類都需要一個不同的靜態后備存儲,但又希望能夠從一個實例多態地訪問狀態,則可以執行以下操作:

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實現,包括使用支持靜態存儲。 請注意,這不一定是一個好主意,因為這種棘手的全局狀態(假裝為實例屬性)可能會使您的代碼難以理解和維護。

這是一個錯誤,因為c泛型類型參數而不是類型 靜態成員只能通過類型訪問。

如果我將相關語句替換為ax = 10,可以嗎? 如果不是,ax與cx(或hx,其中h是a的子類)有什么不同?

您確實可以將語句替換為ax=10; 如您所見,這意味着bxcxdx也都等於10。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM