2017-10-08 2 views
1

私は奇妙な動作があります。外部静的拡張呼び出しを動的に入力して動的にキャストする

次のメソッドを使用して、オブジェクトを任意の型にキャストします。

using System.Dynamic; 

...例えば

/// <summary> 
/// Casts any object to passed type. 
/// </summary> 
/// <typeparam name="T">Wished type</typeparam> 
/// <param name="obj">The object you want to be casted.</param> 
public static T ToType<T>(this object obj) => (T)obj; 

(動的にオブジェクト):

AnyLabel.Tag = new ExpandoObject(); 
AnyLabel.Tag.ToType<dynamic>().Item2 = new Form(); // works 

ここで、次のような状況(型指定されたオブジェクトへの動的):

// var is NOT from type form, why?: 
var form = ToType<Form>(AnyLabel.Tag.ToType<dynamic>().Item2); 

// the other way works like desired: 
var form2 = ((Form)AnyLabel.Tag.ToType<dynamic>().Item2); 

I cを使用してフォームのプロパティ/メソッドにアクセスすることはできませんラàasting拡張子:

ToType<Form>(AnyLabel.Tag.ToType<dynamic>().Item2).Show(); 

私の質問は、なぜ最初のVaRはないタイプのフォームからのものであり、私に実行するための最後のコード部分を拒否していますか?

+0

コードはコンパイルできませんでした。コンパイル可能なコードを投稿してください。 –

+0

編集されました。 – Bagerfahrer

+0

拡張メソッドを拡張メソッドとして使用しないときに、その拡張メソッドを定義するのはなぜですか? – oerkelens

答えて

1

ToType<T>()のメソッドは、オーバーロードされたバージョンを持つ可能性があります。ダイナミクスが含まれていない場合、コンパイラはコンパイル時に適切なオーバーロードを解決します。もし、ダイナミクスが関与している場合、バインディングは実行時に発生します。つまり、実行時に引数のランタイム・タイプを使用して正しいオーバーロードが決定されます。また、これらのオーバーロードは異なる戻り値の型を持つ可能性があります。現在のところ、この戻り値の型はコンパイル時には分かりません。C#コンパイラは関数の戻り値の型としてdynamicを選択します。

ここでは、オーバーロードされたバージョンがなく、安全に使用できると考えられる理由が考えられます。Formしかし、後で過負荷を追加するとどうなりますか?これは突然変更されなかった式の戻り値の型を変更する必要がありますか?オーバーロードを追加すると、コンパイル時に検出できない既存のコードに大きな変更が導入されます。


オーバーロードが実行時引数型によって決まる場合、コンパイル時に選択する戻り値の型はどれですか?

public static T ToType<T>(this object obj) => (T)obj; 
public static int ToType<T>(this int i) => i; // Makes no sense, but valid code. 
public static dynamic ToType<T>(this dynamic d) => d; // Valid as well. 
+0

10回読んだ後、私はそれを理解しました。だから、私の誤解は、期待された結果だけを考えることでした。ありがとう! – Bagerfahrer

+0

オーバーロードの解像度はあなたのヌードルを焼くことができます。 –

+0

あなたは偉大な答えの根底に、ソリューションを追加することができます:ToType

((オブジェクト)AnyLabel.Tag.ToType ().Item2).Show(); 'これは、参照したいオーバーロードを示します。これはあなたの答えを丸め、これを見つけるすべての人に役立ちます。 – Bagerfahrer

関連する問題