2016-10-16 2 views
2

이의 내가 하나가 다른으로 전환 두 개의 클래스가 있다고 가정 해 봅시다 : 잘못된 캐스트 예외 객체 매개 변수로 전달하면

public class Foo { } 

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

지금 나는 그것이 Foo에 캐스트 매개 변수로 객체를 기대하는 방법이 있습니다. 전화 통화 DoSomething(bar)InvalidCastException을 발생 예상으로 DoSomething(foo) 작동하는 동안

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

DoSomething(foo); 
DoSomething(bar); 

:

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

는 지금은이 방법과 같이 호출합니다. 두 번째 메서드 호출에서 런타임에서 사용자 정의 형식 변환 연산자를 사용할 수없는 이유는 무엇입니까?

답변

7

두 번째 메서드 호출에서 런타임에서 사용자 정의 형식 변환 연산자를 사용할 수없는 이유는 무엇입니까?

컴파일러는 실행 시간에 수행되지 않기 때문에이 사용자 - 정의 된 변환은 컴파일러 아닌 실행에 의해 발견된다. 값이 실제로 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에 매개 변수의 컴파일 타임 유형을 변경할 수 있다면 더 좋을 것이다 ... 당신이 할 수없는 이유가 무엇입니까? 이 대리자를 일치하기 때문에

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

내가 매개 변수 유형을 변경할 수 없습니다 : 당신이 모든 매개 변수 유형을 변경할 수없는 경우, 당신은 항상 방법 dynamic로 변환 할 수 있습니다. –

+1

@ThomasSchremser : -; 예를 들어 '당신은 방법은'dynamic'을 받아들이와 방법 그룹 변환과'액션 '만들 수 있습니다 내 대답의 주요 예제를, 당신은'액션 행동 = 해봐요을 사용할 수 있습니다. –

관련 문제