.NET Core를 사용한 동적 메서드 호출

안녕 모두! 오늘은 .NET Core로 "동적 메서드 호출"을 수행하는 몇 가지 방법을 살펴보겠습니다.

이미 아시는 분들도 계시겠지만 저는 얼마 전에 오픈 소스 프로젝트OpenSleigh 작업을 시작했습니다. .NET Core 애플리케이션용 Saga 관리 라이브러리입니다.

나는 지난 기간 동안 그것에 많이 집중해 왔으며 이로 인해 불행히도 내 블로그에 덜 부지런해졌습니다. 내 백로그에 몇 가지 기사가 있는데, 모자에서 뛰어내릴 적절한 시간을 찾고 있습니다.

어쨌든, OpenSleigh의 첫 번째 프로토타입을 작업하는 동안(BTW, 적어도 포크 또는 스타the repository !) 흥미로운 문제에 여러 번 직면해야 했습니다.

매우 빠르게 요약해 보겠습니다.

어떤 인스턴스에서 메서드를 호출해야 하지만 우리가 아는 유일한 것은 클래스 유형이 아니라 메서드 서명뿐이라면 어떻게 될까요?



까다로운 상황이지만 다행스럽게도 .NET에는 목적지에 도달할 수 있는 몇 가지 방법이 있습니다.

이제 문제는 다음과 같습니다. 어느 것이 최고입니까?

그래서 나는 그것을 시도하고 몇 가지 벤치마크를 작성하기로 결정했습니다. 테스트했습니다:
  • 직접 메서드 호출
  • MethodInfo.Invoke
  • Delegate.DynamicInvoke
  • Func<> 호출
  • dynamic  캐스트

  • 물론 *직접 메서드 호출 *은 다른 모든 기술의 기준인 비교로 사용됩니다.

    여기에 이 ​​작은 클래스가 있다고 가정해 보겠습니다.

    public class Foo
    {
        public int Bar(int a, int b, bool c) => a + (c ? b : 0);
    }
    


    인스턴스에서 Bar()를 호출하고 싶지만 *객체만 있으면 됩니다. 각각의 기술을 살펴보자.


    메서드 정보.호출

    Bar()에 대한 MethodInfo 참조를 저장하는 것으로 시작한 다음 간단히 호출합니다.

    object fooInstance = ...; // we get this from somewhere else
    MethodInfo barMethod = ClassType.GetMethod(nameof(Foo.Bar));
    barMethod.Invoke(fooInstance, new[] { (object)1, (object)2, (object)false });
    




    대리자.DynamicInvoke

    이 경우 대신 MethodInfo *참조를 가져오는 것으로 시작하지만 유형이 지정된 *Delegate로 래핑합니다.

    object fooInstance = ...; // we get this from somewhere else
    MethodInfo barMethod = ClassType.GetMethod(nameof(Foo.Bar));
    var delegateType = Expression.GetDelegateType(typeof(Foo), typeof(int), typeof(int), typeof(bool), typeof(int));
    var @delegate = Delegate.CreateDelegate(delegateType, barMethod);
    @delegate.DynamicInvoke(new[] { fooInstance, (object)1, (object)2, (object)false });
    




    Func<> 호출

    이전과 유사하지만 Delegate *를 *Func<>로 캐스팅합니다.

    object fooInstance = ...; // we get this from somewhere else
    MethodInfo barMethod = ClassType.GetMethod(nameof(Foo.Bar));
    var delegateType = Expression.GetDelegateType(typeof(Foo), typeof(int), typeof(int), typeof(bool), typeof(int));
    var func = (Func<Foo, int, int, bool, int>)Delegate.CreateDelegate(delegateType, barMethod);
    func(fooInstance as Foo, 1, 2, false);
    


    인스턴스가 Foo 유형이라는 것을 실제로 알고 있기 때문에 이것은 약간 "음영"처럼 보입니다. 그러나 여전히 유용할 수 있으므로 그룹에 추가하기로 결정했습니다.


    다이나믹 캐스트

    이것은 기본적으로 동적 및 메서드 호출로의 캐스트이므로 코딩하기 가장 쉽습니다(물론 직접 호출 후).

    object fooInstance = ...; // we get this from somewhere else
    dynamic dynamicFoo = fooInstance as dynamic;
    dynamicFoo.Bar(1, 2, false);
    


    자, 이 모든 소란 끝에 승자는 누구입니까? 이미지는 천 단어의 가치가 있다고 생각합니다.



    보시다시피 메서드를 직접 호출하는 것이 확실히 가장 빠른 방법입니다. 즉시 "shady"*Func<> *호출과 *동적 *캐스트가 이어집니다.

    평소처럼 code to GitHub을(를) 푸시했으므로 자유롭게 실험을 실행하고 알려주세요!

    좋은 웹페이지 즐겨찾기