첫 번째 샘플에는 덮개 아래에서 수행 한 캐스트가 있습니까?
예, 말할 수 있습니다!
Combine
메서드는 .NET C#이없는 .NET 1로 작성되었습니다. Combine
의 공식적인 반환 형식 그러므로 Delegate
해야했다 : 모두 a
및 b
이 Action
을 때
가
public static Delegate Combine(Delegate a, Delegate b)
{
...
}
그러나이 방법은 여전히 Action
를 반환합니다. 그리고 예, a
과 b
은 동일한 런타임 유형을 가져야합니다. Combine
로
작성하지 마십시오 MulticastDelegate.Combine
는 System.Delegate
클래스에 의해 정의 된 static
방법이다. 그러므로 Delegate.Combine
라고하면 덜 혼란 스럽습니다.
우회 :
C 번호의 현재 버전과 Combine
이 contravariant 대표 유형 문제가있다. 지금
Action<string> doSomethingToString; // will be assigned below
Action<ICloneable> a = cloneable => { Console.WriteLine("I'm cloning"); cloneable.Clone(); }
Action<IConvertible> b = convertible => { Console.WriteLine("I'm converting"); convertible.ToInt32(CultureInfo.InvariantCulture); }
Action<string> aStr = a; // OK by contravariance of Action<in T>, aStr and a reference same object
Action<string> bStr = b; // OK by contravariance of Action<in T>, bStr and b reference same object
doSomethingToString = aStr + bStr; // throws exception
doSomethingToString("42"); // should first clone "42" then convert "42" to Int32
가정 프레임 워크의 일부 미래 버전은 일반적인 Combine
방법 소개 : 다음 사항을 고려
public static TDel Combine<TDel>(TDel a, TDel b) where TDel : Delegate
{
// use typeof(TDel) to figure out type of new "sum" delegate
}
및 +
새로운 제네릭에 대한 호출로 번역되었다 C 번호는 변경되었습니다 가정 Combine<>
메서드이면 반항 및 위임 조합이 수정 될 것입니다! 나는 그들이 더 높은 우선 순위를 가지고 있다고 말하지만 여전히 그렇다고 생각한다.
class Program
{
static void Main(string[] args)
{
Test1();
Test2();
}
public static void Test1()
{
Action a =() => Console.WriteLine("A");
Action b =() => Console.WriteLine("B");
Action c = a + b;
c();
}
public static void Test2()
{
Action a =() => Console.WriteLine("A");
Action b =() => Console.WriteLine("B");
Action c = (Action)MulticastDelegate.Combine(a, b);
c();
}
}
그런 다음 ILSpy으로보고 :
이 같은 뭔가를해야만 수행 가정 각 대리자 형식은 자신의 정적'Combine' 방법을 정의하는 어떤 근본적인 문제가있을 것인가? 그런 다음 두 대표자 'X'와 'Y'가 둘 다 'FooDelegate'로 대체 할 수있는 두 유형 인 경우 'FooDelegate.Combine (X, Y)'를 사용할 수 있습니다. 공분산 문제가 없더라도'(FooDelegate) Delegate.Combine (X, Y)'보다 깔끔하게 보일 수 있으며 'X'와 'Y'가 적합하다는 컴파일 타임 검사를 추가 할 수 있습니다. – supercat
@supercat 나에게 그것은 좋은 해결책처럼 들린다. –