인터페이스에 정의된 C#4 옵션 매개 변수가 구현 클래스에 적용되지 않는 이유는 무엇입니까?
C# 4의 선택적 매개 변수를 사용하여 인터페이스에 선택적 매개 변수를 지정할 경우 구현 클래스에서 해당 매개 변수를 선택적으로 설정할 필요가 없습니다.
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일자 블로그의 주제였습니다. 좋은 질문 감사합니다!
설명한 대로 인터페이스와 이를 구현하는 100개의 클래스가 있다고 가정합니다.그런 다음 인터페이스 메소드 중 하나의 매개 변수 중 하나를 선택적으로 만들기로 결정합니다.당신은 컴파일러가 개발자에게 그 인터페이스 방법의 모든 구현을 찾도록 강요하고 매개 변수를 선택적으로 만드는 것이 옳은 일이라고 제안하는 것입니까?
우리가 그렇게 했다고 가정해 보세요.이제 개발자가 구현을 위한 소스 코드를 가지고 있지 않다고 가정합니다.
// 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를 배송해 달라고 요청해야 합니까?
그것은 날지 못할 것입니다.두 사람이 B의 저자를 불러 그 중 한 사람은 기본값이 참이고 한 사람은 거짓이 되기를 바란다면요?만약 B의 작가가 단순히 함께 연주하기를 거부한다면요?
아마도 그런 경우에는 다음과 같이 말해야 할 것입니다.
class D : B, MyInterface
{
public new void TestMethod(bool b = false)
{
base.TestMethod(b);
}
}
제안된 기능은 대표적인 파워가 증가하지 않으면서 프로그래머에게 많은 불편을 가중시키는 것으로 보입니다.사용자에게 비용 증가를 정당화하는 이 기능의 강력한 이점은 무엇입니까?
업데이트: 아래 의견에서 슈퍼캣은 언어에 진정으로 힘을 더하고 이 질문에 설명된 것과 유사한 시나리오를 가능하게 하는 언어 기능을 제안합니다.참고로 인터페이스에서 메소드의 기본 구현 기능인 이 기능은 C# 8에 추가됩니다.
선택적 매개 변수에는 특성이 태그될 뿐입니다.이 속성은 컴파일러에게 호출 사이트에 해당 매개 변수의 기본값을 삽입하도록 지시합니다.
»obj2.TestMethod();
는 대됨체로 대체됩니다.obj2.TestMethod(false);
C# 코드가 JIT 시간이 아닌 IL로 컴파일될 때.
그래서 어떤 면에서는 선택적 매개변수로 기본값을 제공하는 것이 항상 발신자입니다.이는 바이너리 버전 관리에도 영향을 미칩니다.기본값을 변경했지만 호출 코드를 다시 컴파일하지 않으면 이전 기본값이 계속 사용됩니다.
반면에, 이 연결 해제는 콘크리트 클래스와 인터페이스를 항상 상호 교환적으로 사용할 수 없다는 것을 의미합니다.
인터페이스 방법이 명시적으로 구현된 경우에는 이미 그렇게 할 수 없습니다.
기본 매개 변수는 런타임이 아닌 컴파일 시간에 확인되기 때문입니다.따라서 기본값은 호출되는 개체가 아니라 호출되는 참조 유형에 속합니다.
선택적 매개변수는 제가 이해한 바로는 매크로 대체와 같습니다.그들은 방법의 관점에서 실제로 선택할 수 있는 것은 아닙니다.인터페이스에 캐스트를 하면 다른 결과를 얻을 수 있는 동작을 볼 수 있습니다.
다른 답변들이 합리적인 설명을 제공하지만 저를 완전히 만족시키는 것은 아니기 때문에 여기에 제 견해를 덧붙이고 싶습니다.
선택적 매개 변수는 호출 사이트에서 기본값의 컴파일 시간 주입을 위한 구문 설탕입니다.이것은 인터페이스/구현과는 아무런 관련이 없으며, 선택적 매개 변수가 있는 메소드의 부작용으로 볼 수 있습니다.그래서, 당신이 그 방법을 부를 때,
public void TestMethod(bool value = false) { /*...*/ }
맘에 들다SomeClass.TestMethod()
,사실 그래.SomeClass.TestMethod(false)
인터페이스에서 이 메서드를 호출하는 경우 정적 유형 검사에서 메서드 시그니처에 선택적 매개 변수가 있습니다.정적 형식 검사에서 선택적 매개 변수가 없는 파생 클래스의 인스턴스에서 이 메서드를 호출하는 경우 메서드 시그니처는 선택적 매개 변수가 없으므로 전체 인수를 사용하여 호출해야 합니다.
선택적 모수가 구현되는 방식으로 인해 자연스러운 설계 결과입니다.
@eric-lippert에 대한 설명 감사합니다.
다음은 몇 가지 코드 예입니다.
[Fact]
public void TestOptionalMethodArgument()
{
var implementation = new TestHello();
IHello @interface = implementation;
Assert.Equal(23, @interface.Action());
Assert.Equal(40, implementation.Action());
}
public class TestHello : IHello
{
public int Action(int number = 40)
=> number;
}
public interface IHello
{
int Action(int number = 23);
}
var obj = new MyClass();
obj.TestMethod(); // compiler error
var obj2 = new MyClass() as MyInterface;
obj2.TestMethod(); // prints false
사용하다
MyInterface obj = new MyClass();
obj.TestMethod(); // compiler error
var obj2 = new MyClass() as MyInterface;
obj2.TestMethod(); // prints false
둘 다 거짓이 됩니다
언급URL : https://stackoverflow.com/questions/4922714/why-are-c-sharp-4-optional-parameters-defined-on-interface-not-enforced-on-imple
'programing' 카테고리의 다른 글
깃 분기의 태그를 다른 커밋으로 이동하려면 어떻게 해야 합니까? (0) | 2023.05.17 |
---|---|
bash에서 스크립트에 선언된 변수를 나열하는 방법은 무엇입니까? (0) | 2023.05.17 |
이클립스 Tomcat 7 빈 서버 이름 추가 (0) | 2023.05.17 |
NSA 속성 문자열은 어떻게 사용합니까? (0) | 2023.05.17 |
C#을 사용하여 REST API로 통화하려면 어떻게 해야 합니까? (0) | 2023.05.17 |