2017-09-24 59 views
0

首先,讓我明確一點,這不是虛擬靜態爲什麼不起作用的另一個問題,因此請避免回答編譯器如何看到虛擬和靜態或將其標記爲這些問題的重複,但是如果您知道任何符合我的示例的答案,請隨時鏈接並標記重複。實現「虛擬靜態」可能有什麼好方法?使用簡單的示例案例

現在,通過摸索如何實現的東西,會一直用此方式解決,也就是很多人說:「我甚至不知道你爲什麼會需要做的」和人們想的幾個例子問同樣的問題,因爲我有很多不同的例子,所以我很難與其他人的答案聯繫起來。

所以,在這個遊戲中,我想讓我有一個簡單的InventoryItem系統。從virtual classItem繼承了Inventory類可以識別

public class Item { 
    public virtual static Sprite getIcon(); 
    public virtual static string getName(); 
} 

public class Stone : Item { 
    static Sprite icon; 
    static string name = "Stone"; 

    public override static Sprite getIcon(){ 
     return icon; 
    } 
    public override static string getName(){ 
     return icon; 
    } 

    // ... 
} 

所以思想基本上是每一個Stone股在Inventory相同icon和所有的石頭具有相同的名稱/標題,說使用調試消息或給玩家一些他正在看或正在拾取的信息。

現在我所有的勇氣告訴我,最好的做法是,Sprite應該是static,因爲在InventoryStone所有實例應該表現出同樣的icon。但是,各種物品也應該有Sprite,因此他們應該用inherit共同get-方法來檢索這些。

於是我想出了兩個備選方案感到傳統錯誤或overkillishly錯誤。

1)使get - 方法非static,讓他們返回靜態成員的內容。這是非常規的,因爲它會爲每個實例返回值相同的每個實例的開銷。

編輯:糾正,沒有額外的開銷,因此這種方法是要走的路。

2)請存儲所有的精靈/名稱和基於給定對象的類型返回他們一些大師班。首先,我不喜歡使用類型比較/檢查,因爲我覺得如果可以的話,最好避免這樣做。但即便如此,我覺得像這樣的解決方案是矯枉過正這些瑣碎的任務返回一個stringSprite參考

所以,除非我失去了一些東西,有沒有實現這一點的直接的方法是什麼?還是我的兩種方法之一比我認爲的要好?

PS:我要實現這一個團結的比賽,因此,如果統一提供的解決方案我所有的耳朵。

+1

*這是非常規的,因爲它會爲類的每個實例開銷,而每個實例的返回值都是相同的。*虛擬方法沒有每個實例的開銷。 – PetSerAl

+0

@PetSerAl我可能使用了錯誤的術語。但是你是否認爲沒有內存/性能的缺點讓所有的方法都不使用靜態方法? – Chexxor

+1

@Chexxor正確,沒有任何懲罰,只需製作一個引用私有靜態字段的普通虛擬方法即可。 –

回答

1

在羅馬,入鄉隨俗做。:)

如果使用C#那麼我建議避免Java風格的編碼。

例如方法名稱是PascalCase而不是camelCase,而C#也有properties而不是getter/setter方法。因此,這裏是我的建議:

public abstract class Item 
{ 
    public abstract Sprite Icon { get; } 

    public abstract string Name { get; } 
} 

public class Stone : Item 
{ 
    private static readonly Sprite icon = Sprite.Create(/* parameters omitted */); 

    private const string name = "Stone"; 

    // expression-bodied member: supported as of C# 6 
    public override Sprite Icon => icon; 

    // traditional propery getter 
    public override string Name 
    { 
     get 
     { 
      return name; 
     } 
    } 
} 

你可以看到什麼位置:

  • 您可以覆蓋性能和標有abstractvirtualoverride關鍵字的方法。我製作了Item類,其屬性爲abstract,因此我不需要實現Item類中的屬性,並且只能派生類型如Stone,它們必須重寫屬性。
  • 由於icon字段的值不會改變,所以我應用了readonly關鍵字以便它不能被更改。
  • name字段可能也readonly但不是static readonly string領域,我們使用const關鍵字,這使得name場不僅static,而且它的價值不能被改變。 請注意:static readonlyconst表現不同,請參閱here
  • 重寫的屬性有兩種形式:Name屬性以傳統的C#方式實現,Icon屬性通過新的expression-bodied member功能實現。

總結一下,沒有冒犯性,我的意圖只是說明如何在更多的C#中實現您的解決方案,而這看起來不像Java。

+0

這個答案證明非常有用!我不知道來自Java的是那麼明顯;)無論如何,這些編碼技巧超過了我的要求,但正是我所需要的,謝謝。 – Chexxor

0

隨着一些澄清提意見,我發現我說的第一個解決方案實際上是直截了當的答案,我一直在尋找。只需將變量設爲靜態,但繼承的/ overriden方法是非靜態的,但使用它來檢索靜態值。

public class Item { 
    public virtual Sprite getIcon(); 
    public virtual string getName(); 
} 

public class Stone : Item { 
    static Sprite icon; 
    static string name = "Stone"; 

    public override Sprite getIcon(){ 
     return icon; 
    } 
    public override string getName(){ 
     return icon; 
    } 

    // ... 
} 
相關問題