2012-03-20 5 views
1

です。機能があります。これは、不明な型の 'item'と呼ばれるオブジェクトを取り込みます。機能では、オブジェクトを宣言し、タイプが何であるかに応じて、オブジェクトは例えば、から値を取得します「アイテム」の何フィールドに依存します: "の文字列を渡し、ダイナミックフィールドは「T」タイプに依存し、ハードコードなし

private static void CreateObject<T>(T item) 
{ 
    SomeObject object = new SomeObject(); 

    //if 'item' is type "A" 
    //   object.Text = item.Display 
    //else if 'item' is type "B" 
    //   object.Text = item.Text 
    //else if 'item' is type "C" 
    //   object.Text = item.Value 


} 

は注意してくださいitem.display '、またはこれはオプションではありません。この関数では多くのことが行われていますが、これは必要なものを説明する関数の簡略化されたバージョンです。

これはもっとエレガントなやり方でできますか?

私は反射を見てきましたが、それはあなたがAdapterパターンを適用し、表示テキストや他のものを返します。アダプタオブジェクトを渡すことができ(ハードウェア、メモリなど)

答えて

1

高価であるとして、これを避けるために指示されて。そのオブジェクトは、呼び出し元が適切に作成できます(おそらく、発信者は、それがCreateObject()に送信しているオブジェクトの性質についてもっと知っているでしょう)。例:だから、メソッドの呼び出し元が使用する

interface IMyAdapter { 
    string GetDisplayText(); 
    // ... 
} 

class TextBoxAdapter : IMyAdapter { 
    private readonly TextBox tb; 

    public TextBoxAdapter(TextBox tb) { 
     this.tb = tb; 
    } 

    public string GetDisplayText() { 
     return tb.Text; 
    } 

    // ... 
} 

... 

public static void CreateObject(IAdapter adapter) { 
    SomeObject obj = new SomeObject(); 
    obj.Text = adapter.GetDisplayText(); 
    // ... 
} 

... 

var textBoxAdapter = new TextBoxAdapter(new TextBox()); 
CreateObject(textBoxAdapter); 
+0

+1 - はい、アダプタパターンは機能しますが、代理人を受け入れる方がはるかに便利です! – VinayC

+0

@VinayC:OPは単なる値を返す以上のことをしたい。彼は、文字列を渡すだけでは不十分だと言いました。これは、他の値がオブジェクトから集められることを意味していました。彼は複数の代議員を通過しなければならないだろう。 – siride

4

Text

private static void CreateObject<T>(T item, Func<T, object> prop) 
{ 
    SomeObject obj = new SomeObject(); 

    obj.Text = prop(item).ToString(); 
} 

を提供しますデリゲートのパラメータを取るデリゲートを渡すことについてErangaの答えに加えて

CreateObject(a, t => t.Display); 
CreateObject(b, t => t.Text); 
// etc 
+0

それはFunc であるべきですか、あるいはおそらくFunc ですら、呼び出し側はToString()を適切に処理できますか? –

+0

@ChrisSaintyはい。それに気づいてくれてありがとう。私は間違ってパラメータを変更しました – Eranga

+0

OPはこう言っています:「このアイテムでは「item.display」の文字列を渡すか、これはオプションではないことに注意してください。これは説明するための機能の簡略版です何が必要ですか?つまり、単一の文字列を取得するだけでなく、おそらくいくつかの追加パラメータを取得するということです。それぞれの代理人を持つことは混乱です。 – siride

0

、呼び出しコード全体に代理人を捨てたくなければ、この関数が非一般的なオーバーロードを作成してそれを行うことができます。

private static void CreateObject<T>(T item, Func<T, string> prop) { 
    SomeObject obj = new SomeObject(); 
    obj.Text = prop(item); 
} 

private static void CreateObject(TypeA item) { 
    CreateObject(item, i => i.Display); 
} 

private static void CreateObject(TypeB item) { 
    CreateObject(item, i => i.Text); 
} 

これは、機能の本体の中央から引き離しながら、デリゲートを集中管理します。

私はあなたができる多くの方法があります

など、それはから呼び出されている場合、我々はこの方法の大きさと目的について多くの詳細を知る必要があるだろう、しかし答える「最高」を与えることを考えます正直なところ、あなたの一連のif文に間違いはありません。明らかなことは、どのプログラマもそれを理解しなければならず、実際の問題を解決するだけで、いくつかのケースしか持たないのです。

+0

これは、 'CreateObject()'を含むクラスが渡されるすべての型を知っている必要があることに注意してください。私はそれが最高のデザインだとは思わないし、OPがそれを1〜 、彼はすでにジェネリックメソッドの代わりにこのパターンを使用していました。 – siride

+0

私が答えて言ったように、「最良の」アプローチは、共有されていないコードの側面に依存します。私は単に別のオプションを強調表示するために私の答えを掲載した。 OPがアプリケーションに適したアプローチを決定するのはOPです。 –

関連する問題