Tác phẩm này (trong C# 4.0 ít nhất - không được thử trong các phiên bản cũ hơn):
SomeDelegate a = Inc;
Func<int, int> c = new Func<int, int>(a);
Nếu bạn nhìn vào IL, điều này được biên dịch chính xác giống như câu trả lời của Winston. Đây là IL cho dòng thứ hai của những gì tôi chỉ viết:
ldloc.0
ldftn instance int32 ConsoleApplication1.Program/SomeDelegate::Invoke(int32)
newobj instance void class [mscorlib]System.Func`2<int32,int32>::.ctor(object, native int)
Và đó cũng là một cách chính xác những gì bạn thấy nếu bạn gán a.Invoke
vào c
.
Ngẫu nhiên, mặc dù giải pháp của Diego hiệu quả hơn, trong đó đại biểu kết quả tham chiếu trực tiếp đến phương thức cơ bản hơn là đi qua đại biểu khác, nó không xử lý chính xác các đại biểu multicast. Giải pháp của Winston, bởi vì nó chỉ hoàn toàn chống lại các đại biểu khác. Nếu bạn muốn có một giải pháp trực tiếp mà cũng xử lý các đại biểu với nhiều mục tiêu, bạn cần một chút gì đó phức tạp hơn:
public static TResult DuplicateDelegateAs<TResult>(MulticastDelegate source)
{
Delegate result = null;
foreach (Delegate sourceItem in source.GetInvocationList())
{
var copy = Delegate.CreateDelegate(
typeof(TResult), sourceItem.Target, sourceItem.Method);
result = Delegate.Combine(result, copy);
}
return (TResult) (object) result;
}
này là điều đúng đắn cho các đại biểu với một mục tiêu duy nhất bằng cách-nó sẽ kết thúc sản xuất chỉ một đại biểu duy nhất của loại mục tiêu đề cập trực tiếp đến bất kỳ phương thức nào (và khi có thể, đối tượng) mà đại biểu đầu vào được nhắc tới.
Nguồn
2012-02-15 09:21:20
Có thể nhấn mạnh vào thực tế các công cụ tùy chỉnh bạn đã viết thường được thực hiện bằng phép thuật biên dịch. – Dykam
+1 để được giải thích tốt đẹp. Có một cách đơn giản hơn * Func c = x => a (x); * mặc dù - xem câu trả lời của tôi. –
Tôi giả sử trong bit cuối cùng 'công khai Foo' nên đã được 'public MyLambda'? – Chris