2012-05-01 16 views
3

私はここで私のビジョンを説明するために最善を尽くすつもりです。これは非常に不自由な構成例です。私はBagのいくつかの異なるタイプを持っていて、それらはすべてMarbleの独自の特殊タイプを保持しています。 Marbleの各タイプにはニックネーム(string秒)があります。リフレクションを使用して静的プロパティ値を取得すると、派生クラスと基底クラスの連結

残念ながら、マーブル・イン・ザ・バッグ以外にも、ジェネリック医薬品は私を助けません。

// Bags 
abstract class Bag { 
    protected Type MarbleType { get; } 
    protected List<Marble> _marbles; 

    public void DumpBag() 
    { ... } 
} 
class RedBag : Bag { 
    override Type MarbleType { get { return typeof(RedMarble); } } 
} 
class BlueBag : Bag { 
    override Type MarbleType { get { return typeof(BlueMarble); } } 
} 

// Marbles 
abstract class Marble { 
    public static IEnumerable<string> Nicknames { 
     get { 
      return new List<string>() { 
       "Marble", "RollyThing" 
      } 
     } 
    } 
} 
class RedMarble : Marble { 
    public static IEnumerable<string> Nicknames { 
     get { 
      return new List<string>(Marble.Nicknames) { 
       "Ruby" 
      }; 
     } 
    } 
} 
class BlueMarble : Marble { ... } 

これで、DumpBag()という実装が実現しました。私は印刷にそれを希望

Bag b = new RedBag(); 
b.GetMarbles(); 
b.DumpBag(); 

Bag of Marbles (aka "Marble", "RollyThing", Ruby"): 
- Marble 1 
- Marble 2 
... 

私たちが向かっていること印刷するために、Bagはの派生型の知識を持つことができなければならない、ことがわかり、次の呼び出しを考えてみましょうMarble、実際のインスタンスから独立しています。 Marble基本クラスのNicknamesの連結を取得しますが、派生したRedMarbleも連結します。

DumpBagは、「静的仮想呼び出し」の種類を行う必要があります。私は次のようにDumpBagを実装し始めました:

public void DumpBag() { 
    PropertyInfo pi = this.MarbleType.GetProperty("Nicknames", BindingFlags.Static); 
    IEnumerable<string> nicknames = pi.GetValue(null, null); // No instance 

    StringBuilder sb = new StringBuilder("Bag of Marbles (aka "); 
    foreach (string nn in nicknames) 
     sb.Append("\"" + nn + "\", "); 
    Console.WriteLine(sb.ToString()); 

    ... 
} 

私の質問:

  1. は、この正気ですか?うまくいけば、なぜ私がこのルートに行ったのかについての私の理論的根拠を説明することができます。
  2. 私は、RedMarble.Nicknamesの隠蔽Marble.Nicknamesを警告(もちろん)します。それは先に進み、それをnewとマークするのが有効なようですか?あなたが不足しているすべての明示キャストで見つけることができます

答えて

3

:私はそれをテストしたとき

(List<string>)this.MarbleType.GetProperty("Nicknames").GetValue(null, null);

これは私のためにうまく働きました。

コメントで説明したように、新しいキーワードを実際に使用するべきではありません。基本クラスの静的メソッドの名前を他のものに変更するほうがよいのであいまいさはありません。あなたは結局このことをコントロールしており、他人のコードを使用していません。


は今、あなたはそれをこのようにすればよいですか?その場合、プロパティはなります、あなたができる第二のものは、この静的ではないを作るているもちろん

abstract class Bag<T> where T:marble { 
    public void DumpBag() 
    { 
     // here you can use 
     // (IEnumerable<string>)typeof(T).GetProperty("Nicknames").GetValue(null, null); 
    } 
} 

class RedBag : Bag<RedMarble> { 
} 

class BlueBag : Bag<BlueMarble> { 
} 

まあ、最初は確かにあなたは型を返すように定義されていません方法ジェネリックを使用したいですMarbleで要約し、RedMarbleBlueMarbleに上書きしてから、DumpBagに直接アクセスして、反射を使用する代わりにNicknamesとしてください。

+0

'Marble.Nicknames' - >' Marble.BaseNicknames'の名前の変更とは別に、あなたのコードの例は私のものとまったく異なりますか?連結は、あなたが 'RedMarble.Nicknames'でそれを持っているのとまったく同じです。 –

+0

私のリフレクションは、 'Bag'自体が扱っている' Marbles 'の型を知らないので、 'Type'を取得するために仮想プロパティを使用し、静的プロパティを取得するためにリフレクションを使用しますそのタイプから。 –

+0

あなたのコードの一部を見逃していなければなりません - あなたが 'Marble.Namesnames'ではなく' Marble.Namesnames'を持っていることに注意してください。あなたの質問のパート2に答えるには、それを新しいものにしないでください。これは本当に継承ではありません。 – yamen

関連する問題