Trong mẫu đầu tiên, dàn diễn viên chỉ được thực hiện dưới vỏ?
Có, bạn có thể nói điều đó!
Phương pháp Combine
được viết bằng .NET 1, nơi không tồn tại chung C#. Kiểu trả về chính thức của Combine
do đó phải được Delegate
:
public static Delegate Combine(Delegate a, Delegate b)
{
...
}
Nhưng phương pháp này vẫn trả về một Action
khi cả hai a
và b
là Action
. Và có, a
và b
bắt buộc phải có cùng loại thời gian chạy.
Vui lòng không viết MulticastDelegate.Combine
là Combine
là phương thức static
được xác định bởi lớp System.Delegate
. Do đó, hãy nói Delegate.Combine
, điều đó ít gây nhầm lẫn.
Đường vòng:
Phiên bản hiện tại của C# và Combine
có vấn đề với các loại đại biểu contravariant. Hãy xem xét những điều sau đây:
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
Bây giờ, giả sử một số phiên bản tương lai của khuôn khổ này đã giới thiệu một Combine
phương pháp chung:
public static TDel Combine<TDel>(TDel a, TDel b) where TDel : Delegate
{
// use typeof(TDel) to figure out type of new "sum" delegate
}
và giả sử C# được thay đổi như vậy +
đã được dịch sang một cuộc gọi đến generic mới Combine<>
phương pháp, sau đó contravariance và sự kết hợp đại biểu sẽ được cố định! Tôi đoán họ nói với chúng tôi rằng họ có những ưu tiên cao hơn, nhưng vẫn còn.
Nên có bất kỳ vấn đề cơ bản với từng loại đại biểu xác định tĩnh 'Combine' phương pháp riêng của mình? Sau đó, nếu hai đại biểu 'X' và' Y' là cả hai loại được thay thế cho một 'FooDelegate', người ta có thể sử dụng' FooDelegate.Combine (X, Y) '. Ngay cả khi không có vấn đề hiệp phương sai, điều đó có vẻ sạch hơn '(FooDelegate) Delegate.Combine (X, Y)', và có thể thêm một kiểm tra biên dịch thời gian mà 'X' và' Y' là phù hợp. – supercat
@supercat Với tôi nghe như một giải pháp tốt. –