2009-09-14 70 views
7
public class ClassA 
{ 
    public static readonly string processName; 
} 

public class ClassB : ClassA 
{ 
    static ClassB() 
    { 
     processName = "MyProcess.exe"; 
    } 
} 

編譯上述C#代碼時出現錯誤。指定爲基類的靜態只讀字段

錯誤說 - 「靜態只讀域不能被分配到(除靜態構造函數或變量初始值)」

但我在靜態構造函數分配它。

對這樣一個靜態變量的需求是,基類具有使用此變量的方法,但派生類和基類對於此變量必須具有不同的值。但是,在各個班級的所有實例中,價值都是不變的。它必須是隻讀的,因爲它不能在任何地方改變。

上述代碼中的錯誤是什麼? (如果有的話)我似乎無法找到一個。錯誤消息不起作用。因爲我沒有按照它做任何錯誤。

如果出現錯誤,我該如何實現此功能?我知道一個簡單的解決方法是將其設爲實例變量並在派生類中爲它們分配不同的值。但這是不必要的,因爲在各個班級的所有實例中價值都是不變的。

回答

14

雖然您正在分配錯誤的靜態構造函數。它只能在聲明變量的類型的靜態構造函數中分配。

假設您有另一個派生自ClassC的類來做同樣的事情 - 您最終會覆蓋該變量,該變量意味着只讀。這裏有一個單個的靜態變量,但是你有很多派生類。

答案之一是避免使用靜態可變但把一個虛擬屬性在基類,和使每個派生類重寫屬性返回不同的常數:

public class ClassA 
{ 
    public virtual string ProcessName { get { return "ClassAProcess"; } } 
} 

public class ClassB : ClassA 
{ 
    public override string ProcessName { get { return "MyProcess.exe"; } } 
} 

基本上選項可能會將「靜態」位分隔爲一個單獨的層次結構 - 實際上,它聽起來像您希望在該類型而不是實例上使用多態,而.NET中不支持該類型。

+1

正是! 「類型上的多態性」。我不認爲這可能是更恰當的措詞。感謝您指出它在.NET中不受支持。 – Poulo

5

在您的示例中,只有一個字段將存在,即基類的字段,並且不能在單個字段中具有不同的值。除此之外,您只能在同一個類中初始化readonly字段,而不是在派生類中。一種解決方法,可以定義一個通用類,如:

static class ProcessNames<T> { 
    public static string Value { get; set; } 
} 

,並使用ProcessNames<DerivedClassType>.Value代替。顯然,價值將以這種方式公開訪問。

但是,您應該看看在每個派生類中定義字段是否分別適合您的需求,並且只有在不適用時才使用變通辦法。

1

皮膚有很多種方法。這是另一種可以做到的方式。

public class ClassA 
{ 
    public string ProcessName{ get; private set;} 

    public ClassA() 
    { 
     ProcessName = "ClassAProcess"; 
    } 

    public ClassA(string processName) 
    { 
     ProcessName = processName; 
    } 
} 

public class ClassB : ClassA 
{ 
    public ClassB() : base("ClassAProcess") 
    { 
    } 
} 
+0

但這隻適用於實例變量,它並不能真正實現想要的 –