30

试图使Feature通用,然后突然编译器说

操作员 '?' 不能应用于“T”类型的操作数

这是代码

public abstract class Feature<T>
{
    public T Value
    {
        get { return GetValue?.Invoke(); } // here is error
        set { SetValue?.Invoke(value); }
    }

    public Func<T> GetValue { get; set; }
    public Action<T> SetValue { get; set; }
}

可以改用此代码

get
{
    if (GetValue != null)
        return GetValue();
    return default(T);
}

但我想知道如何修复那个漂亮的 C# 6.0 单线。

4

3 回答 3

43

由于并非所有内容都可以是null,因此您必须缩小范围T以使其可以为空(又名 an object)。结构不能为空,枚举也不能。

添加whereonclass确实可以解决问题:

public abstract class Feature<T> where T : class

那么为什么它不能正常工作呢?

Invoke()产量T。如果GetValuenull,则?运算符将 type 的返回值设置Tnull,但它不能。例如,如果Tint,它不能使其为空(int?),因为所需的实际类型(T= int)不是。

如果您更改Tint在您的代码中,您将非常清楚地看到问题。你问的最终结果是这样的:

get
{
    int? x = GetValue?.Invoke();
    return x.GetValueOrDefault(0);
}

这不是空传播运算符将为您做的事情。如果您恢复使用default(T)它确实知道该做什么,并且您避免了“有问题的”空传播。

于 2015-09-15T07:53:29.553 回答
8

T必须是引用类型或可为空的类型

public abstract class Feature<T> where T : class
{
    // ...
}
于 2015-09-15T07:53:24.210 回答
4

据我所知,?.运算符是硬编码的,可以使用null,也就是说,它适用于引用类型或可空值类型,但不适用于普通值类型。null如果表达式是null而不是 ,则该问题很可能是运算符返回default(T)

您可以通过限制Tclass此处来修复它。

于 2015-09-15T07:53:07.883 回答