2017-09-24 4 views
0

まず、仮想静的機能が動作しない理由の別の質問ではありませんので、コンパイラが仮想と静的をどのように見ているかを解説したり、これらの質問の重複としてフラグを立ててください私の例に合った答えをあなたが知っていれば、自由にリンクして、重複していることに気をつけてください。"Virtual Static"には何があるのでしょうか?単純な例文の場合

このようにして解決されたものを実装する方法を探ることによって、「なぜあなたはそれを行う必要があるのか​​わからない」と多くの人がいます。私には非常に異なる例があるので、同じ質問をしてください。だから私は他人の答えに関連づけるのが難しいと思っています。

このゲームでは、私は単純なInventoryItemシステムを持っていたいと思っています。 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; 
    } 

    // ... 
} 

そう思ったが、基本的にあなたのInventoryでそのすべてのStone株式同じiconであり、すべての石が同じ名前/タイトルを持っていることを、デバッグに使用するための言うことを認識することができることをvirtual classからすべてItem継承メッセージを表示したり、プレーヤーが見ているものやピックアップしているものに関するメッセージをプレーヤーに与えたりすることができます。

今、すべての私の根性は、ベストプラクティスはInventoryStoneのすべてのインスタンスが同じiconを示さなければならないので、Spriteは、staticでなければならないことであることを教えてください。ただし、すべての種類のアイテムにはSpriteも含まれている必要があります。したがって、get-methodを取得するのはinheritです。

私が思いついた2つの選択肢は、従来は間違っていたり、過度に間違っていると感じます。

1)get-methodsをstaticにして、静的メンバーの内容を返すようにします。これは、戻り値がすべてのインスタンスで同じであるクラスのすべてのインスタンスに対してオーバーヘッドを作成するので、従来とは異なります。

編集:修正:余分なオーバーヘッドがないため、この方法が有効です。

2)は、すべてのスプライト/名前を格納し、指定されたオブジェクトのタイプに基づいて、それらを返すいくつかのマスタークラスを作成します。まず第一に、タイプ比較/チェックを使用するのは好きではありません。できるだけそのようにするのが最善であるという印象です。しかし、たとえそうであっても、このソリューションは、私は何かが欠けていない限り、stringまたはSprite参照だから、

を返すようなささいなタスクのためにやり過ぎのように私は感じて、これを達成するのストレートフォワードな方法何もありませんか?それとも私の2つの方法のうちの1つは、私が思うよりも優れていますか?

PS:私は統一は、私はすべての耳だソリューションを提供しますので、もしつもりが、ユニティゲームのためにこれを実装しますよ。私が述べた最初のソリューションは、実際に私が探していたストレートフォワードな答えであることがわかったコメンターからいくつかの明確化

+1

*これは、戻り値がすべてのインスタンスで同じであるクラスのすべてのインスタンスに対してオーバーヘッドを作成するため、これには類を見ないものです。*仮想メソッドにはインスタンスごとのオーバーヘッドはありません。 – PetSerAl

+0

@PetSerAl間違った用語を使用した可能性があります。しかし、そのようなメソッドに静的メソッドを使用しないというメモリ/パフォーマンスの欠点はまったくないと言っていますか? – Chexxor

+1

@Chexxor correct、それにペナルティはありません。プライベート静的フィールドを参照する通常の仮想メソッドを作成するだけです。 –

答えて

1

。:)

C#を使用している場合は、Javaスタイルのコーディングを避けることをお勧めします。

たとえば、メソッド名はcamelCaseフォームの代わりにPascalCaseフォームであり、C#もgetter/setterメソッドの代わりにpropertiesです。だからここに私の提案です:

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; 
     } 
    } 
} 

あなたはここで見ることができます:あなたはabstractまたはvirtualまたはoverrideキーワードでマークされたプロパティとメソッドをオーバーライドすることができ

  • を。私はItemクラスとそのプロパティをabstractとして作ったので、Itemクラスのプロパティを実装する必要はなく、Stoneのような派生型しかプロパティをオーバーライドする必要があります。
  • iconフィールドの値が変更されないため、変更することができないようにreadonlyキーワードを適用しました。
  • nameフィールドもreadonlyではなく、私たちだけではなくnameフィールドを作るstaticだけでなく、その値を変更することはできませんconstキーワードを使用static readonly stringのフィールドである可能性があります。 注意:static readonlyconstの動作は異なります。hereを参照してください。
  • オーバーライドされたプロパティは2つのフォームにあります。Nameプロパティは従来のC#の方法で実装され、Iconプロパティは新しいexpression-bodied memberフィーチャで実装されます。

私の意図は、あなたのソリューションをJavaのように見えないC#のより多くの方法で実装する方法を示すことだけでした。

+0

この回答は非常に便利です!私はJavaから来るのかどうかは分かりませんでした;)とにかく、これらのコーディングのヒントは私が求めている以上のものでした。 – Chexxor

0

。単純に変数を静的にしますが、継承/オーバーライドされたメソッドは静的ではありませんが、静的な値を取得するために使用します。ローマ人がそうであるように、ローマでは、やる

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; 
    } 

    // ... 
} 
関連する問題