Dot-Net

如何投射 lambda?

  • September 8, 2012

我希望將一系列函式保存在從某種基類型派生的字典中(例如,讓我們將基類稱為“對象”)。那麼,是否可以將 f1 保留在 f2 中?

Func<bool> f1 = () => true;
Func<object> f2 = f1;

錯誤 1 無法將類型隱式轉換System.Func<bool>System.Func<object>

這是我們能做的最好的嗎?

Func<bool> f1 = () => true;
Func<object> f2 = () => (object)f1;

錯誤:(無)

我想它需要通用友好的是 where 語句……但我不確定你是否可以用 lamdas 做到這一點。


跟進 Armen 的資訊,我深入研究了 string 和 bool 的定義:

public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable,
                            IComparable<String>, IEnumerabl<char>,
                            IEquatable<String> 

public struct Boolean : IComparable, IConvertible, IComparable<Boolean>,
                       IEquatable<Boolean>

他對 ref Vs 價值的看法是正確的。String 是否隱式地從對象派生?根據@PeterK的連結,這似乎是結構的行為。

“ValueType 使用更合適的值類型實現覆蓋來自 Object 的虛擬方法。另請參見繼承自 ValueType 的 Enum。”

目的:

System.Object:所有類、結構、列舉和委託。(來自http://msdn.microsoft.com/en-us/library/system.object

這反過來又使得Func<bool>不能分配給Func<object>有點愚蠢。即從那個角度來看,繼承層次結構是正確的。

這裡(強調我的):

協變使您可以使用比泛型參數指定的類型更多的派生類型。這允許實現變體介面的類的隱式轉換和委託類型的隱式轉換。引用類型支持協變和逆變,但值類型不支持它們

還有

差異僅適用於引用類型;如果為變體類型參數指定值類型,則該類型參數對於生成的構造類型是不變的。

原因可能與 C# 和 CLI 在歷史上如何處理(並且不同意)值類型的數組共變異數有關。在這裡查看一些資訊。

所以你看,類型參數的共變異數Func<out TResult>不適用於值類型,所以你必須這樣做:

Func<object> f2 = () => f1();

引用自:https://stackoverflow.com/questions/12330090