2009-05-06 8 views
8

私はC#(C#4 dynamic keyword - why not?)の動的機能に非常に興奮しています。特に、コードの特定のライブラリ部分では、多くのリフレクションを使用しています。C#4.0の "dynamic"キーワードはGenericsを冗長化しますか?

私の質問は二つです:

1.「ダイナミック」以下の場合のように、ジェネリックを交換するのですか?

ジェネリックメソッド:

public static void Do_Something_If_Object_Not_Null<SomeType>(SomeType ObjToTest) { 

     //test object is not null, regardless of its Type 
     if (!EqualityComparer<SomeType>.Default.Equals(ObjToTest, default(SomeType))) { 
      //do something 
     } 
    } 

動的方法(??):

public static void Do_Something_If_Object_Not_Null(dynamic ObjToTest) { 

     //test object is not null, regardless of its Type?? but how? 
     if (ObjToTest != null) { 
      //do something 
     } 
    } 

2.以下の場合のように、今匿名型を返すための方法を可能にする "動的" し?:

public static List<dynamic> ReturnAnonymousType() { 
     return MyDataContext.SomeEntities.Entity.Select(e => e.Property1, e.Property2).ToList(); 
    } 

cool、cheers

EDIT:

もう少し私の質問を通じて考えた、と回答の光の中で、私は完全にメインのジェネリック/ダイナミック質問を台無しに参照してください。彼らはまったく異なっています。そう、すべての情報をありがとう。

ただし、ポイント2はどうですか?

答えて

16

dynamicは、反射シナリオ限られた数の簡素化かもしれない(あなたはアップフロントメンバー名を知っているが、何のインタフェースはありません) - 特に、それは一般的な演算子(although other answers exist)に役立つかもしれない - しかし、以外ジェネリック演算子のトリック、ジェネリックスとのクロスオーバはほとんどありません。

ジェネリックはあなたが作業しているタイプについて(コンパイル時に)知ることができるように - 逆に、dynamicは、種類についてケアはしていません。 特にジェネリックスを使用すると、多くの条件を指定して証明することができます。については、タイプです。つまり、インタフェースを実装している場合や、パブリックなパラメータのないコンストラクタがある場合などです。 dynamicは、インターフェイスをサポートしていません。インターフェイスを気にしないだけでなく、明示的インターフェイス実装dynamicを参照することもできません。

さらに、dynamicは実際にはobjectという特別なケースです。ボクシングはプレイに参加しますが、それはvengenceです。

現実には、いくつかの例にdynamicの使用を制限する必要があります。

  • COM相互運用機能
  • DLRの相互運用
  • 多分入力していくつかの光のアヒル
  • 多分いくつかの一般的なのオペレータ

それ以外の場合は、ジェネリックスと通常のC#を使用してください。

+1

ダイナミックスのもうひとつの魅力的な使い方:RESTfulなWeb状況でのJSON interop - 特に問題のJSONがコールからコールへと大きく変動する場合動的オブジェクトとの間でJSONを直列化および非直列化するライブラリがあります。 – Randolpho

8

最初の質問に答えるために、ジェネリックは実行時にコンパイル時の動的型を解決します。したがって、タイプの安全性と速度には明確な違いがあります。

+2

完全性のために、.NETのジェネリックはランタイムによって提供され、必要に応じて実行時にジェネリック型引数を指定することができます。 –

+0

@Peter:thanks peter。私は実装の点でもっと考えていました。実際にGenericsの代わりに "Dynamic"を使用していますが、私の例ではObject – andy

6

動的クラスとジェネリックスは全く異なる概念です。ジェネリックでは、コンパイル時に型を定義します。彼らは変化しない、彼らは動的ではありません。いくつかのクラスまたはメソッドに "プレースホルダ"を置くだけで、呼び出しコードが型を定義するようになります。

動的メソッドは実行時に定義されます。コンパイル時に型の安全性がありません。動的クラスは、オブジェクト参照があり、文字列名でリフレクションを使用してメソッドを呼び出す場合と似ています。

3

2番目の質問への回答:C#3.0で匿名型を返すことができます。型をオブジェクトにキャストして戻し、リフレクションを使用してメンバーにアクセスします。動的キーワードは、そのための文法的な砂糖です。

+0

に感謝しています。だから、C#4.0では、私はオブジェクトの代わりに動的を返すことができますし、反射を使用する必要はありませんか? – andy

+0

はいできます。匿名型を返すメソッドの戻り値の型としてdynamicを使用します。その後、リフレクションを使わずにメンバーにアクセスできます。 – Maggie

16

質問にお答えします。あなたは、データの種類のコードの独立を書く -

  • ジェネリック医薬品は、あなたに「アルゴリズムの再利用」を与えます。動的キーワードはこれに関連する何もしません。私はList<T>を定義し、文字列、intsなどのリストのために使用することができます。
  • タイプ安全:全体のコンパイル時チェックの議論。動的変数は、コンパイル時の警告/エラーを警告することはありません。間違いを犯した場合、実行しようとしたメソッドが見つからないと実行時に爆発します。静的対動的型式の議論
  • パフォーマンス:ジェネリックスは、値型を使用してアルゴリズム/コードのパフォーマンスを大幅に向上させます。それは私たちにプレジェネリックスを費やすボクシング - アンボクシングサイクル全体を防ぎます。ダイナミックはこれでも何もしません。あなたはクラスの名前またはオブジェクトモデルを指定する必要はありません何dynamicキーワードはあなたを与えるだろうさ

    • シンプルなコード(あなたはエクセルと相互運用しているとき言うことができます。)

    。適切なメソッドを呼び出すと、その時点でオブジェクトに存在するメソッドが呼び出されると、そのメソッドが呼び出されます。コンパイラでは、メソッドが定義されていなくても手を離れます。しかし、これは、動的なvarフィールド/メソッドを呼び出す前にCLRがチェックを実行する必要があるため、コンパイラが検証/静的型のメソッド呼び出しを行うよりも時間がかかることを意味します。

  • 動的変数は、異なる時点で異なる種類のオブジェクトを保持できます。特定のファミリまたはオブジェクトの種類に拘束されていません。
+0

Gishu、すばらしい答えに感謝します。あなたとマルクの間に50/50だった。だから本当に1つ以上の答えを許可する必要がありますか?もう一度ありがとうございます – andy

関連する問題