2011-11-14 3 views
4

고려 다음과 같은 콘솔 응용 프로그램 :이 프로그램의 출력은 C# 4.0의 기본 매개 변수

class Program 
{ 
    static void Main() 
    { 
     MyInterface test = new MyClass(); 
     test.MyMethod(); 

     Console.ReadKey(); 
    } 
} 

interface MyInterface 
{ 
    void MyMethod(string myString = "I am the default value on the interface"); 
} 

class MyClass : MyInterface 
{ 
    public void MyMethod(string myString = "I am the default value set on the implementing class") 
    { 
     Console.WriteLine(myString); 
    } 
} 

입니다

:

I am the default value on the interface 

(1) 당사 매개 변수로를 지정하는 방법이 아니다 값을 제공하지 않고 인터페이스에서 선택 사항. 기본값을 구현 세부 사항으로 간주합니다. 이 코드를 사전 옵션 매개 변수 스타일로 작성하면 인터페이스에 두 개의 오버로드를 만들고 기본값은 구현 클래스에 지정됩니다. 나는. 우리는 할 것이다 :

우리가 기대하는 것처럼 출력
interface MyInterface 
{ 
    void MyMethod(); 

    void MyMethod(string myString); 
} 

class MyClass : MyInterface 
{ 
    public void MyMethod() 
    { 
     MyMethod("I am the default value set on the implementing class"); 
    } 

    public void MyMethod(string myString) 
    { 
     Console.WriteLine(myString); 
    } 
} 

,

I am the default value set on the implementing class 

(2) 왜 우리는 구현 클래스의 기본 값을 재정의 할 수 없습니다!

답변

4

.Net의 기본값은 실제로 컴파일러 기반 구문 설탕입니다. 호출 사이트에서 컴파일러는 기본값을 사용자에 대해 추가합니다. 컴파일 타임에 객체의 런타임 유형을 알 수 없으므로 인터페이스에 정의 된 값을 삽입해야합니다.

따라서 무시할 것이 없으므로 구현에서 '재정의'될 수 없습니다.

에릭 Lippert의는 here을 찾을 수있는 첫 번째있는 선택적 인수의 주제에 블로그 게시물의 매우 흥미로운 시리즈를 썼다.

업데이트 귀하의 의견, 당신이 제안하고 어느 CLR가있는 것 (실행시의 형태가 선언 된) '가상'매개 변수의 일부 형태에 대해 '알고있다'됩니다에서
. 필자는이 구현이 비용 (설계, 문서화, 구현, 테스트 등)이 제공 한 이점에 비해 너무 높았 기 때문에 제외되었다고 추측합니다 (이것은 단지 추측 일뿐입니다!).

void M(bool y = false) { ... whatever ... } 

과 같이 컴파일러에 의해 다시 작성 가져옵니다 :

void M() { M(false); } 
void M(bool y) { ... whatever ... } 

그러나이 경로가 과부하 한 번에 여러 선택적 인수의 가능성이 수용 할 수없는 수준에 이르게 추락 는 다른 방법으로, 기본 위임 방법 옵션 즉있다 그리고 명명 된 논쟁은 considertaion으로 간주됩니다.

+0

부유 한 건배, 나는 문제를 본다. 인터페이스에 값을 제공하지 않고 "선택적"키워드를 추가하는 것이 더 합리적이지 않습니까? 인터페이스에 기본값을 두어야한다는 것은 나에게 의미가 없습니다. – magritte

3

1) 생각에 결함이 있습니다. 기본값은 구현 세부 사항이라고합니다. 인터페이스에는 구현 세부 사항이 없습니다. 그 논리에 의해, 디폴트 값을 지정하는 것은 실제로 인터페이스에 속하지 않습니다.

오버로드 된 메서드를 사용하여 인터페이스를 작성하기 만하면됩니다. 정의가보다 명확해질뿐만 아니라 다른 언어와 인터페이스 할 때 인터페이스가 더 호환 될 것이므로 선택적 매개 변수와 함께 제공되는 버전 문제는 발생하지 않습니다.

2) 인터페이스가 운영 계약을 정의하기 때문입니다. 인터페이스는 기본값이 뭔가 있어야한다고 말합니다. 따라서 클래스는이를 구현해야합니다.

+0

(1) 실제로 매개 변수가 선택 사항인지 알 수 없으므로 생략하면 컴파일러 경고가 표시됩니다. 이것은 내 질문 (1) 왜 값을 제공하지 않고 선택적으로 지정할 수 없습니다 리드? – magritte

+0

@ 토니 리퍼 (Toony Leeper) - 트위터를 통해 에릭 리 퍼트 (Eric Lippert)의 모범 사례를 얻었습니다. http://blogs.msdn.com/b/ericlippert/archive/2011/05/09/optional-argument-corner-cases-part -one.aspx –