2013-01-01 18 views
10

私はこの拡張メソッドを書いた:IEnumerable <dynamic>に変換しますか?

public static class A 
{ 
public static IEnumerable<dynamic> AsDynamic<T>(this IEnumerable<T> f) 
    { 
     foreach (var element in f) 
     { 
       yield return (dynamic) element; 
     } 
    } 
} 

をして、それをテストした:

List<int> l = new List<int>(){1,2,3}; 
Console.WriteLine (l.AsDynamic().GetType()); 

出力があるしかし:typeof (IEnumerable<Object>)

  • それはtypeof (IEnumerable<dynamic>)ないのはなぜ?

  • どのように私はそれのようにすることができますか?

+2

["ほとんどの場合、型オブジェクトのように機能します。"](http://msdn.microsoft.com/en-us/library/dd264736.aspx) –

+1

実行時には 'dynamic'型はありませんそれらは単にオブジェクトとしてタイプされ、メソッドバインディング情報は動的変数を含む各呼び出しサイトで出力されます。 – Lee

答えて

21

あなたは何を誤解していると思いますかdynamic。基本的には、オブジェクトの型がdynamicであることをコンパイラに指示すると、実行時にのオブジェクトは、コンパイル時ににという不具合を出さずに、呼び出すメソッドまたはプロパティをサポートすることを約束します。また、あなたが約束を破ると、あなたはその結果に直面することを約束します。

あなたは、オブジェクトがdynamicであると言う

は、コンパイラは型に関する仮定を行うことができないので、何がobjectとして保存することができることを知って、object使用しています。あなたがIEnumerable<dynamic>を行うと、それは大きな違いの1つに、IEnumerable<object>次のようになります、original.AsDynamic()dynamicオブジェクトのシーケンスを与えるので

IEnumerable<SomeType> original = ... 
foreach (dynamic x in original.AsDynamic()) { // Using your method 
    Console.WriteLine(x.SomeUnsupportedMethod()); // The compiler is silent! 
} 

:あなたは、その要素上の任意のメソッドを呼び出すことができ、およびコンパイラが言葉を言うことはありませんコンパイラはSomeUnsupportedMethodへの呼び出しについて不平を言うことはありません。メソッドが実際に実行時にサポートされていない場合、プログラムはクラッシュします。メソッドが実際にSomeTypeの要素でサポートされている場合、クラッシュは発生せず、メソッドが呼び出されます。

これはすべてdynamicで行います。静的には、「プレースホルダー」はobjectのままで、typeofはあなたに多くを伝えます。しかし、オブジェクトの正確な機能(メソッドとプロパティ)は実行時まで検査されません。

+1

私は他の答えに対するコメントの議論から理解するように、 'typeof(IEnumerable )'は実際にはC#では有効ですが有用ではありませんが、 'typeof(IEnumerable )'と同じランタイムタイプを作成します。しかし、 'typeof(dynamic)'は 'typeof(object)'の同義語として許されません。ちなみに、 'GetType()'はインターフェースタイプを返すことはないので、オリジナルのポスターは正確ではありませんでした。 –

+0

@JeppeStigNielsen http://i.stack.imgur.com/9C4sD.jpg –

+0

@RoyiNamir私はあなたのスクリーンショットを理解していません(私はLINQPadに慣れていません)。 2つの行には異なる書体があります。 2つの 'WriteLine'メソッド呼び出しの出力ではありません。 'GetType()'は 'RuntimeType'オブジェクトを返します。最初の' WriteLine'に 'ToString()'メソッドが呼び出されます。型は反復子ブロック( 'yield returns')を持っているため、生成された型(' <', '> 'と奇妙な名前のクラス、' __'文字があります)になります。これを試してみてください: 'if(l.AsDynamic()。GetType()== typeof(IEnumerable ))throw new exception(" Jeppe was wrong! ");' –

0

Linq拡張メソッドCast()を試してください。しかし、私はそれが動的で動作するかどうかはわかりません。

0

dynamicはダイナミック型

Console.WriteLine(typeof(dynamic)); // error 

は単に設計することによってランタイム

+0

MSDNは「型」も参照しています。[Visual C#2010は動的な新しい型を導入しました](http://msdn.microsoft.com/en-us/library/dd264736.aspx) –

+0

@ Some1.Kill.The。 DJ - 'typeof(dynamic)'を使用しようとするとコンパイルエラーが発生します。「typeof演算子は動的型では使用できません」 – Lee

+0

@Lee 'dynamic'は実行時に知られていない型です.dynamicとobjectは似ていますが、動的以外はコンパイル時には実行できません – Anirudha

1

における実際の型を解決していないので、ランタイムバインディングは、バインディング静的と同様できるだけとして振る舞います。

ので、実行時の型は、静的な型はまたtypeof (IEnumerable<dynamic>)

ランタイム扱い、この真のだろうtypeof (IEnumerable<Object>)

だろう概念的

typeof(object)==typeof(dynamic) 

ので、

Aダイナミックタイpeはオブジェクトと似ていますが、コンパイル時に知られていない方法で使うことができます。

関連する問題