10

我希望将一系列函数保存在从某种基类型派生的字典中(例如,让我们将基类称为“对象”)。那么,是否可以将 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>有点愚蠢。即从那个角度来看,继承层次结构是正确的。

4

2 回答 2

3

如果您使用的是 .NET 4.0+,这是可能的。

您的示例不起作用,因为 bool 是一种值类型。但是,如果您要使用字符串更改 bool,则该示例有效。

    Func<string> f1 = () => "true";
    Func<object> f2 = f1;
于 2012-09-08T11:07:39.827 回答
3

这里(强调我的):

协变使您可以使用比泛型参数指定的类型更多的派生类型。这允许实现变体接口的类的隐式转换和委托类型的隐式转换。引用类型支持协变和逆变,但值类型不支持它们

还有

差异仅适用于引用类型;如果为变体类型参数指定值类型,则该类型参数对于生成的构造类型是不变的。

原因可能与 C# 和 CLI 在历史上如何处理(并且不同意)值类型的数组协方差有关。在这里查看一些信息。

所以你看,类型参数的协方差Func<out TResult>不适用于值类型,所以你必须这样做:

Func<object> f2 = () => f1();
于 2012-09-08T15:07:00.147 回答