2009-05-05 493 views
36

我最近遇到了一個問題,它似乎我需要'靜態抽象'方法。我知道爲什麼這是不可能的,但我該如何解決這個限制?C#,實現'靜態抽象'像方法

例如,我有一個抽象類,它有一個描述字符串。由於這個字串是通用於所有的情況下,它被標記爲靜態的,但我想需要從這個類派生的所有類提供自己的描述屬性,因此我將其標記爲抽象:

abstract class AbstractBase 
{ 
    ... 
    public static abstract string Description{get;} 
    ... 
} 

它不會當然編譯。我想過使用接口,但接口可能不包含靜態方法簽名。

我應該讓它變得非靜態,並且總是得到一個實例來獲取該類的特定信息嗎?

任何想法?

+0

與此問題類似http://stackoverflow.com/questions/763344/c-virtual-or-abstract-static-methods/763364#763364 – 2009-05-05 07:07:14

+0

可能的重複[爲什麼我不能在C#中使用抽象靜態方法? ?](https://stackoverflow.com/questions/3284/why-cant-i-have-abstract-static-methods-in-c) – 2018-01-10 04:57:47

+0

[如何實現虛擬靜態屬性?](https:/ /stackoverflow.com/questions/15346631/how-to-implement-virtual-static-properties) – peterh 2018-01-10 11:13:37

回答

5

結合靜態和抽象是沒有意義的,是的。靜態背後的想法是不需要爲了使用有問題的成員而提供類的實例;然而,對於抽象,我們期望一個實例是一個派生類,它提供了一個具體的實現。

我可以看到爲什麼你想要這種組合,但事實是唯一的效果是拒絕'this'或任何非靜態成員的實現使用。也就是說,即使調用抽象或'靜態抽象'成員之間沒有根本的區別(因爲兩者都需要一個具體的實例來找出使用什麼實現),父類將決定對派生類的實現進行限制,

31

你不能。

要做到這一點的地方是屬性。

[Name("FooClass")] 
class Foo 
{ 
} 
3

它不是靜態的,如果它有一個實例被調用。

如果你不是在實例上調用它,那麼在播放時就沒有多態性(即就語言而言,ChildA.Description與ChildB.Description完全無關)。

5

如果它是靜態的,只有一個變量的實例,我不明白如果我們可以在派生類中使用靜態變量來完成你想完成的工作,那麼繼承是有意義的。就我個人而言,我認爲你要儘量避免實例變種。

爲什麼不只是經典的方式?

abstract class AbstractBase 
{ 
    protected string _Description = "I am boring abstract default value"; 
} 

class Foo : AbstractBase { 

    public Foo() { 
     _Description = "I am foo!"; 
    } 
} 
5

如果你不介意推遲到實現明智地實施Description屬性,你可以簡單地做

public abstract string ClassDescription {get; } 
// ClassDescription is more intention-revealing than Description 

而且實現類會做這樣的事情:

static string classDescription="My Description for this class"; 
override string ClassDescription { get { return classDescription; } } 

然後,你的班級必須遵守描述的合同,但你要讓他們明智地做到這一點。沒有辦法以面向對象的方式指定實現(除非通過殘酷,脆弱的黑客)。

但是,在我看來,這個描述是類元數據,所以我更願意使用其他人描述的屬性機制。如果您特別擔心多次使用反射,請創建一個反映您所關注屬性的對象,並在「類型」和「描述」之間存儲字典。這將最大限度地減少反射(除了運行時類型檢測,這並不是那麼糟糕)。字典可以存儲爲通常需要此信息的任何類的成員,或者,如果域中的客戶端需要它,可以通過單例或上下文對象進行存儲。

0

您可以使「抽象」基本方法拋出Exception,因此如果開發人員試圖在不重寫的情況下在子類上調用此方法,則會「警告」開發人員。

缺點是可能會擴展類而不使用此方法。然後參考提供的其他答案。