2013-04-20 12 views
2

나는 이것이 가능하다는 것을 오늘보고 놀랐다. 그러나 나는 이것이 전에 논의되어야한다고 걱정한다.C#은 구조형 입력이 없다는 것을 절대적으로 알고있는 이유는 무엇입니까?

public interface ICanAdd 
{ 
    int Add(int x, int y); 
} 

// Note that MyAdder does NOT implement ICanAdd, 
// but it does define an Add method like the one in ICanAdd: 
public class MyAdder 
{ 
    public int Add(int x, int y) 
    { 
     return x + y; 
    } 
} 

public class Program 
{ 
    void Main() 
    { 
     var myAdder = new MyAdder(); 
     var iCanAdd = (ICanAdd)myAdder; //compiles, but for what sake? 
     int sum = iCanAdd.Add(2, 2); //na, not game for it, cast had already failed 
    } 
} 

위의 상황에서 컴파일러는 명시 적 캐스트가 존재 함을 알 수 있습니다. 나는 거기에서 구조적인 타이핑을 감지하기 위해 모두 감격했지만 런타임에는 실패하지 않았다. C#이 언제 여기서 도움이 되었습니까? 그러한 캐스팅과 같은 시나리오는 효과가 있습니까? 그것이 무엇이든, 저는 컴파일러가 myAdder이 정확히 기술적으로는 ICanAdd이 아니라는 것을 알고 있습니다.

+2

왜 downvoted? 다른 두뇌 방귀 세션이 있습니까? – nawfal

+0

좋은 질문입니다! '가산기'의 '가산기'는 어디에 있습니까? 'iCanAdd'를 원하셨습니까? – dasblinkenlight

+0

@dasblinkenlight 예. 나는 오타를 편집 할 것이다 :) 그러나 어쨌든 그 선은 명중되지 않는다. – nawfal

답변

9

C#에서는 클래스가 인터페이스를 구현하지 않아도 (클래스가 해당 인터페이스를 구현하지 않아도) 명시 적 변환을 허용합니다. 왜냐하면 모든 컴파일러에서 특정 유형이 실제로있을 수 있습니다 (불확실성은 암시 적 변환이 아닌 명시 적 이유입니다) 이 인터페이스를 구현하는 파생 유형의 인스턴스가됩니다. 귀하의 예제를 확장, 당신은 가정 :

public class DerivedAdder : MyAdder, ICanAdd 
{ 
    int ICanAdd.Add(int x, int y) 
    { 
    return base.Add(x, y); 
    } 
} 

... 

MyAdder myAdder = new DerivedAdder(); 
var iCanAdd = (ICanAdd)myAdder; // Valid in this case 
int sum = iCanAdd.Add(2, 2); // sum = 4 

당신이 C# Specification의 섹션 6.2.4을 선택하면, 당신은 당신이 sealed 같은 MyAdder 클래스를 표시하는 경우, 컴파일러는 실제로 불평 것을 볼 수 있습니다 다음 것 때문에 파생 된 유형이 존재할 수 없으므로 변환이 불가능하다는 것을 확실히 알고 있어야합니다. 그러나 의심의 여지를 없앨 수없는 한 명시적인 변환을 허용합니다.

+0

귀하의 의견을 통해 귀하의 답변이 업데이트되었습니다. 희망은 그 ok. – nawfal

1

인터페이스에 대한 캐스팅 클래스는 C# language specification까지 허용됩니다. 그러나 예를 들어 ICanAdd가 클래스 컴파일 인 경우