[C#] 인터페이스에 정의 된 C # 4 선택적 매개 변수가 클래스 구현시 적용되지 않는 이유는 무엇입니까?

당신은 당신이 인터페이스에서 선택적 매개 변수를 지정하면 나는 C # 4의 선택적 매개 변수와 그 눈치 t는, 돈 어떤 구현 클래스의 해당 매개 변수의 선택을해야합니다 :

public interface MyInterface
{
    void TestMethod(bool flag = false);
}

public class MyClass : MyInterface
{
    public void TestMethod(bool flag)
    {
        Console.WriteLine(flag);
    }
}

따라서:

var obj = new MyClass();
obj.TestMethod(); // compiler error

var obj2 = new MyClass() as MyInterface;
obj2.TestMethod(); // prints false

선택적 매개 변수가 이런 식으로 작동하도록 설계된 이유를 아는 사람이 있습니까?

한편으로는 인터페이스에 지정된 기본값을 재정의하는 기능이 정직하지만 유용하지만 인터페이스에 기본값을 지정할 수 있는지 여부는 확실하지 않지만 구현 결정이 필요하다고 생각합니다.

반면에,이 연결 해제는 구체적 클래스와 인터페이스를 항상 호환 적으로 사용할 수있는 것은 아닙니다. 물론 구현에 기본값이 지정된 경우 문제가되지 않지만 구체적인 클래스를 인터페이스로 노출하는 경우 (예를 들어 일부 IOC 프레임 워크를 사용하여 콘크리트 클래스를 주입하는 경우) 실제로는 없습니다. 호출자가 항상 기본값을 제공해야합니다.



답변

업데이트 : 이 질문은 2011 년 5 월 12 일에 제 블로그의 주제였습니다. 훌륭한 질문에 감사드립니다!

설명하는 인터페이스와이를 구현하는 백개의 클래스가 있다고 가정하십시오. 그런 다음 인터페이스 메소드 중 하나의 매개 변수 중 하나를 선택적으로 작성하기로합니다. 컴파일러가 개발자가 해당 인터페이스 메소드의 모든 구현을 찾아서 매개 변수를 선택 사항으로 만들도록 강요하는 것이 옳은 일이라고 제안하고 있습니까?

우리가 그렇게했다고 가정 해보십시오. 이제 개발자에게 구현을위한 소스 코드가없는 것으로 가정하십시오.


// in metadata:
public class B
{
    public void TestMethod(bool b) {}
}

// in source code
interface MyInterface
{
    void TestMethod(bool b = false);
}
class D : B, MyInterface {}
// Legal because D's base class has a public method 
// that implements the interface method

D의 저자는 이것을 어떻게해야합니까? 그들은 세계에서 전화로 B의 작성자를 불러서 메소드에 선택적 매개 변수를 갖도록 B의 새로운 버전을 보내달라고 요청합니까?

그것은 날지 않을 것입니다. 어떤 경우 2 개의 사람들은 B의 저자 호출, 그 중 하나는 기본 사실이되고 싶어 그 중 하나는 거짓되고 싶어? B의 저자가 단순히 게임을 거부하면 어떻게 될까요?

아마도이 경우에는 다음과 같이 말해야합니다.

class D : B, MyInterface
{
    public new void TestMethod(bool b = false)
    {
        base.TestMethod(b);
    }
}

제안 된 기능은 대표 력의 상응하는 증가없이 프로그래머에게 많은 불편 함을 추가하는 것으로 보인다. 사용자에게 증가 된 비용을 정당화하는이 기능의 강력한 이점은 무엇입니까?


업데이트 : 아래 의견에서 supercat은 언어에 진정한 힘을 더하고이 질문에 설명 된 것과 유사한 시나리오를 가능하게하는 언어 기능을 제안합니다. 참고로,이 기능 (인터페이스의 기본 메소드 구현)은 C # 8에 추가됩니다.


답변

선택적 매개 변수에는 속성이 태그로 지정되어 있습니다. 이 속성은 컴파일러에게 호출 매개 변수에 해당 매개 변수의 기본값을 삽입하도록 지시합니다.

C # 코드가 JIT 시간이 아닌 IL로 컴파일 될 때 호출 obj2.TestMethod();이 대체됩니다 obj2.TestMethod(false);.

따라서 항상 호출자가 선택적 매개 변수와 함께 기본값을 제공합니다. 또한 이진 버전 관리에 영향을줍니다. 기본값을 변경했지만 호출 코드를 다시 컴파일하지 않으면 이전 기본값이 계속 사용됩니다.

반면에,이 연결 해제는 구체적 클래스와 인터페이스를 항상 호환 적으로 사용할 수있는 것은 아닙니다.

인터페이스 메소드가 명시 적 으로 구현 된 경우 이미 그렇게 할 수 없습니다 .


답변

기본 매개 변수는 런타임이 아닌 컴파일 타임에 해결되기 때문입니다. 따라서 기본값은 호출되는 오브젝트가 아니라 호출되는 참조 유형에 속합니다.


답변

선택적 매개 변수는 내가 이해 한 매크로 대체와 같습니다. 메소드의 관점에서 실제로 선택 사항은 아닙니다. 그 결과는 인터페이스로 캐스트 할 때 다른 결과를 얻는 위치에 나타나는 동작입니다.


답변