2014-10-18 2 views
4

나는 프로그래머이며 게으른입니다. 현재 C#에서 일부 OpenAL 래퍼로 작업하고 있습니다. OpenAL 메서드를 호출 할 때마다 GetError을 사용하여 OpenAL에서 오류를 요청해야합니다. 예외가 있으면 throw합니다. 다음 함수를 포함하는 정적 도우미 클래스를 추가하기까지는 시간이 오래 걸리지 않았습니다.일반 메서드에 대한 Action/Func의 확장 메서드

public static void Check() 
    { 
     ALError error; 
     if ((error = AL.GetError()) != ALError.NoError) 
      throw new InvalidOperationException(AL.GetErrorString(error)); 
    } 

이것은 잠시 동안 작동했지만 더 싶었습니다. 그래서 잠시 후, 나는 다음과 같은 방법을 함께했다 : 이것은 좋은 일

public static void Call(Action function) 
    { 
     function(); 
     ALHelper.Check(); 
    } 

    public static void Call<TParameter>(Action<TParameter> function, TParameter parameter) 
    { 
     function(parameter); 
     ALHelper.Check(); 
    } 

    public static TReturn Eval<TReturn>(Func<TReturn> function) 
    { 
     var val = function(); 
     ALHelper.Check(); 
     return val; 
    } 

    public static TReturn Eval<TParameter, TReturn>(Func<TParameter, TReturn> function, TParameter parameter) 
    { 
     var val = function(parameter); 
     ALHelper.Check(); 
     return val; 
    } 

,하지만, 난 여전히 사용하는 경우 코드가 모습을 정확하게에 행복하지 않았다, 그래서 나는 한 단계 더 걸릴하기로 결정했다 : 위의 메소드를 확장 메소드로 변환했습니다. ActionFunc 매개 변수로 메소드를 전달할 수 있음을 알았으므로 확장 메소드에 대해 잘 작동하여 추악한 handles = ALHelper.Eval(AL.GenBuffers, amount)을보다 세련된 handles = AL.GenBuffers.Eval(amount)으로 바꿨을 것이라고 생각했습니다.

슬프게도, 일단 내가 이것을 사용하기 시작하면 예외적으로 환영 받았다. 식은 method group', where a 변수 ', value' or type'이 필요함을 나타냅니다.

이것이 작동하지 않는다고 슬프지만, 실제로 이것이 작동하지 않는 이유에 대해 궁금해졌습니다. Action 또는 과 같은 메서드를 전달할 수있는 이유는 무엇입니까?하지만 확장 메서드를 사용하면 작동하지 않습니다. 이것은 내가 사용하고있는 Mono 컴파일러 (.NET 4.0)의 제한 사항인가요? 아니면 사용중인 다른 것이 있습니까?

답변

1

handles = ALHelper.Eval(AL.GenBuffers, amount)을 쓸 때 AL.GenBuffers은 어떤 형식의 대리자가 아닙니다. 오버로드 분석은 ALHelper.Eval의 모든 오버로드를 고려하고 표현식 AL.GenBuffers을 변환 할 수있는 델리게이트 유형 하나를 찾습니다.

handles = AL.GenBuffers.Eval(amount)을 쓸 때 AL.GenBuffers은 여전히 ​​모든 유형의 대리인이 아니므로 AL.GenBuffers.Eval은 어떤 방법과도 일치하지 않으며 과부하 해결로는 가장 적합한 일치 항목을 찾을 수 없습니다.

new Func<T, TResult>(AL.GenBuffers).Eval(...)을 작성할 수 있습니다. 원칙적으로 확장 메서드는 대리자 형식에서 작동하지만 사용자가 이미 가지고있는 것보다 더 나쁩니다.

이것은 모노와 관련이 없습니다.

내가 대신 할 것은 클래스를 생성하고 (MyAL라고 가정 해 봅시다) AL의 모든 기능에 대한 래퍼를 제공하는 것입니다. 그러면 발신자는 handles = MyAL.GenBuffers(amount);라고 말할 수 있습니다.

+0

고마워요. 나는 이미 이것과 비슷한 것을 기대 했었지만 이것을 자세히 설명하는 것이 좋다. 실제로 AL에 대한 래퍼 클래스를 만드는 것을 이미 고려했습니다.이 클래스는 문제를 해결하는 데 도움이 될 수 있지만 지금은 함수를 인수로 전달하는 방법을 계속 사용합니다. – Tom

2

확장 방법의 개념을 잘못 이해했다고 생각합니다. 유형을까지 확장하는 데 사용됩니다. 이 경우 AL.GenBuffers은 메서드입니다. Func 또는 Action.이 아닙니다. 시그니처와 호환 될 수는 있지만 그것이 함수 나 동작 또는 다른 종류의 대리자 유형은 아닙니다. 귀하의 예에서는 method group conversions 때문에 AL.GenBuffers과 같이 전달할 수 있습니다. 컴파일러에서 메서드 서명이 호환되는지 확인하면 컴파일러는 delegate 형식으로 변환합니다.

관련 문제