programing tip

정적 메소드가 인스턴스 메소드를 호출하는 C # 컴파일러가 오류 코드를 작성하지 않는 이유는 무엇입니까?

itbloger 2020. 8. 6. 08:01
반응형

정적 메소드가 인스턴스 메소드를 호출하는 C # 컴파일러가 오류 코드를 작성하지 않는 이유는 무엇입니까?


다음 코드에는 Foo()인스턴스 메소드를 호출하는 정적 메소드가 있습니다 Bar().

public sealed class Example
{
    int count;

    public static void Foo( dynamic x )
    {
        Bar(x);
    }

    void Bar( dynamic x )
    {
        count++;
    }
}

오류 *없이 컴파일되지만 런타임에 런타임 바인더 예외를 생성합니다. 이러한 메소드에 대한 동적 매개 변수를 제거하면 예상대로 컴파일러 오류가 발생합니다.

그렇다면 왜 동적 매개 변수를 사용하여 코드를 컴파일 할 수 있습니까? ReSharper는 오류로 표시하지 않습니다.

편집 1 : * Visual Studio 2008에서

편집 2 :sealed 서브 클래스에 정적 Bar(...)메소드 가 포함될 수 있으므로 추가되었습니다 . 봉인 된 버전조차도 인스턴스 메소드 이외의 메소드를 런타임에 호출 할 수 없을 때 컴파일됩니다.


어떤 이유로 든, 과부하 해상도 는 정적 및 비정 적을 확인 하기 전에 항상 가장 일치하는 것을 찾습니다 . 모든 정적 유형으로이 코드를 시도하십시오.

class SillyStuff
{
  static void SameName(object o) { }
  void SameName(string s) { }

  public static void Test()
  {
    SameName("Hi mom");
  }
}

가장 좋은 과부하는을 사용하는 것이므로 컴파일되지 않습니다 string. 그러나 이것은 인스턴스 방법이므로 컴파일러는 두 번째로 과부하가 걸리는 대신 불평합니다.

추가 : 나는의 설명 생각 그래서 dynamic원래의 질문의 예는 일관되게하기 위해, 즉이다 유형의 동적 때, 우리는 또한 최초의 등 유일한 매개 변수 수 및 매개 변수 유형이 아닌 정적 대 비 확인 (최적의 과부하를 찾을 수 - 정적) 확인한 다음 정적 확인하십시오. 그러나 이는 정적 검사가 런타임까지 기다려야 함을 의미합니다. 따라서 관찰 된 행동.

늦은 추가 : Eric Lippert 의이 블로그 게시물 에서이 재미있는 순서를 수행하기로 선택한 이유에 대한 배경 지식 .


Foo에는 동적 "x"매개 변수가 있습니다. 이는 Bar (x)가 동적 표현식임을 의미합니다.

Example에서 다음과 같은 방법을 사용할 수 있습니다.

static Bar(SomeType obj)

이 경우 올바른 방법이 해결되므로 Bar (x) 문은 완벽하게 유효합니다. Bar (x) 인스턴스 메소드가 있다는 사실은 관련이 없으며 고려조차되지 않습니다. 정의에 따르면 Bar (x)는 동적 표현식이므로 런타임에 대한 해상도를 연기했습니다.


"동적"표현식은 런타임 중에 바인드되므로 올바른 서명 또는 인스턴스 메소드로 정적 메소드를 정의하면 컴파일러가이를 확인하지 않습니다.

The "right" method will be determined during runtime. The compiler can not know if there is a valid method there during runtime.

The "dynamic" keyword is defined for dynamic and script languages, where the Method can be defined at any time, even during runtime. Crazy stuff

Here a sample which handles ints but no strings, because of the method is on the instance.

class Program {
    static void Main(string[] args) {
        Example.Foo(1234);
        Example.Foo("1234");
    }
}
public class Example {
    int count;

    public static void Foo(dynamic x) {
        Bar(x);
    }

    public static void Bar(int a) {
        Console.WriteLine(a);
    }

    void Bar(dynamic x) {
        count++;
    }
}

You can add a method to handle all "wrong" calls, which could not be handled

public class Example {
    int count;

    public static void Foo(dynamic x) {
        Bar(x);
    }

    public static void Bar<T>(T a) {
        Console.WriteLine("Error handling:" + a);
    }

    public static void Bar(int a) {
        Console.WriteLine(a);
    }

    void Bar(dynamic x) {
        count++;
    }
}

참고URL : https://stackoverflow.com/questions/12842712/why-does-the-c-sharp-compiler-not-fault-code-where-a-static-method-calls-an-inst

반응형