2016-10-16 13 views
2

はの私は、一方が他方に転換され、二つのクラスがあるとしましょう:今、私はそれがFooにキャストパラメータとしてオブジェクトを期待するメソッドを無効なキャスト例外オブジェクトパラメータとして渡されたときに、

public class Foo { } 

public class Bar 
{ 
    public static implicit operator Foo(Bar bar) => new Foo(); 
} 

を持っています。

public void DoSomething(object o) 
{ 
    var foo = (Foo)o; 
    /* Do something with foo here */ 
} 

は今、私はそうのように、このメソッドを呼び出します。

var bar = new Bar(); 
var foo = (Foo)bar; 

DoSomething(foo); 
DoSomething(bar); 

期待通りのコールDoSomething(bar)InvalidCastExceptionをスローコールDoSomething(foo)作品ながら。 2番目のメソッド呼び出しでランタイムがユーザー定義型変換演算子を使用できないのはなぜですか?

答えて

7

なぜ、ランタイムは2番目のメソッド呼び出しでユーザー定義型変換演算子を使用できませんか?

コンパイラは実行時に実行されていないので...ユーザー定義の変換はコンパイラ、いない実行時に気づかされます。値が実際にFooでない限り、あなたが持っているキャストは、基本的には常に失敗します。

ここでは、動的な型指定を使用する方法があります。メソッドパラメータの型をdynamicにすると、実行時にコンパイラ(ある程度)実行され、変換が見つかります。

例:

もちろん
using System; 

public class Foo { } 

public class Bar 
{ 
    public static implicit operator Foo(Bar bar) => new Foo(); 
} 

class Test 
{ 
    static void Main(string[] args) 
    { 
     var bar = new Bar(); 
     var foo = (Foo)bar; 

     DoSomething(foo); 
     DoSomething(bar); 
    } 

    static void DoSomething(dynamic o) 
    { 
     var foo = (Foo) o; 
    } 
} 

、あなたが実際に代わりFooにあなたのパラメータのコンパイル時の型を変更することができれば、それは良いでしょう...あなたはそれを行うことができない何らかの理由がありますか?あなたがすべてで、パラメータの種類を変更することができない場合、あなたはいつもの方法でdynamicに変換することができることに注意してください:

static void DoSomething(object o) 
{ 
    var foo = (Foo) (dynamic) o; 
} 
+0

それはデリゲートを一致させる必要があるため、私は、パラメータの種類を変更することはできません。 –

+1

@ThomasSchremser: 'Action 'メソッドグループの変換を、 'dynamic'を受け入れるメソッドで作成することができます。私の答えの主な例では、' Action action = DoSomething; 'を使うことができます。 –

関連する問題