구체적인 구현 대신 기본 메소드를 호출하는 방법


9

C # 8에서 기본 인터페이스 방법의 동작이 변경된 이유는 무엇입니까? 과거에 다음 코드 (기본 인터페이스 메소드가 데모가 릴리스되지 않은 경우) :

interface IDefaultInterfaceMethod
{
    // By default, this method will be virtual, and the virtual keyword can be here used!
    virtual void DefaultMethod()
    {
        Console.WriteLine("I am a default method in the interface!");
    }

}

interface IOverrideDefaultInterfaceMethod : IDefaultInterfaceMethod
{
    void IDefaultInterfaceMethod.DefaultMethod()
    {
        Console.WriteLine("I am an overridden default method!");
    }
}

class AnyClass : IDefaultInterfaceMethod, IOverrideDefaultInterfaceMethod
{
}

class Program
{
    static void Main()
    {
        IDefaultInterfaceMethod anyClass = new AnyClass();
        anyClass.DefaultMethod();

        IOverrideDefaultInterfaceMethod anyClassOverridden = new AnyClass();
        anyClassOverridden.DefaultMethod();
    }
}

다음과 같은 출력이 있습니다.

콘솔 출력 :

나는 인터페이스의 기본 방법입니다!
재정의 된 기본 방법입니다!

그러나 C # 8의 마지막 버전에서는 위의 코드가 다음과 같은 출력을 생성합니다.

콘솔 출력 :

재정의 된 기본 방법입니다!
재정의 된 기본 방법입니다!

왜 이런 행동이 바뀌 었는지 설명해 줄 수 있습니까?

노트 :

IDefaultInterfaceMethod anyClass = new AnyClass(); anyClass.DefaultMethod();

((IDefaultInterfaceMethod) anyClass).DefaultMethod(); // STILL the same problem!??

2
디폴트 인터페이스 방법이 없었다 전에 두 번째 출력이 예상되는 경우는 C # 8. - 당신은 인터페이스 메서드를 구현할 때, 당신은 기대 호출 할 수 있습니다. 구형 사양을 언급하고 있습니까? 나는 인터페이스 방법의 예상되는 행동을 나누기 때문에이 버려진 기대
파나지오티스 Kanavos

3
더 좋은 질문은 "구체적인 구현 대신 기본 메소드를 어떻게 호출 할 수 있습니까?"입니다. 대답은 "아직 할 수 없습니다. base.DefaultMethod () 구문이 C # 8에서 삭제
되었으므로

4
다음은 C # 8에 대한 기본 통화를 논의하고 삭제 한 설계 회의 페이지Cut base() syntax for C# 8. We intend to bring this back in the next major release. 입니다. 제대로 작동하려면 런타임 지원이 필요합니다.
Panagiotis Kanavos

3
인터페이스는 항상 인터페이스입니다. 인터페이스 메소드를 구현할 때 모든 클라이언트가 구현 된 메소드를 호출 할 것으로 예상 합니다 . 클라이언트 는 메소드를 구현하는 클래스를 신경 쓰지 않아야합니다. 인터페이스를 가져 와서 호출합니다.
Panagiotis Kanavos

2
당신이 게시 된 구문에 관해서는, 그것은 것이어야 정말 오래된 제안 - 어두워은 명시 적으로 구현 된 인터페이스와 같이 명시 적으로 호출 할 수 있습니다. , 할 ... 않는 명시 적 인터페이스 구문을 사용하여도 그 제안에 반대virtual것 같아요? 그리고 아마도 상속 다이아몬드를 소개합니다
Panagiotis Kanavos

답변:


6

더 좋은 질문은 다음과 같습니다.

구체적인 구현 대신 기본 메소드를 어떻게 호출 할 수 있습니까?

효율적인 구현을 위해서는 런타임 지원이 필요하기 때문에이 기능은 계획되었지만 2019 년 4 월 C # 8에서 중단되었습니다 . 출시 전에 시간 내에 추가 할 수 없습니다. 이 기능은 C #과 VB.NET 모두에서 잘 작동해야합니다. F #은 인터페이스를 좋아하지 않습니다.

런타임에 BM이 없으면 AM ()이 호출됩니다. base () 및 인터페이스의 경우 런타임에서이를 지원하지 않으므로 대신 호출에서 예외가 발생합니다. 런타임에이 기능에 대한 지원을 추가하고 싶지만이 릴리스를 만들기에는 너무 비쌉니다.

몇 가지 해결 방법이 있지만 원하는 동작이 없으며 선호하는 코드 생성기가 아닙니다.

C #에 대한 구현은 실제로 원하는 것은 아니지만 VB 구현은 훨씬 더 어려울 수 있습니다. 또한 VB를 구현하려면 인터페이스 구현 방법이 공용 API 표면이어야합니다.

그것은 작동 하는 관통 base()호출 방법 클래스 작업과 유사. 제안 예제 쿠핑 :

interface I1
{ 
    void M(int) { }
}

interface I2
{
    void M(short) { }
}

interface I3
{
    override void I1.M(int) { }
}

interface I4 : I3
{
    void M2()
    {
        base(I3).M(0) // What does this do?
    }
}

답을 표시하기 전에 잠시 그대로 두겠습니다. 어쩌면 당신은 당신의 좋은 일에 대한 투표를 할 것입니다 :-) 감사합니다!
Bassam Alugili

1
누군가가 한 달 전에 비슷한 것을 물었 기 때문에 @BassamAlugili 만 . 그때 나는 그래도 Why would you do that?. 그런 다음 회의 시간을 알았습니다
Panagiotis Kanavos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.