我遇到了C#编译器的怪异行为(VS 2015)。
在下面的代码中,编译器对Value2感到满意,但提示Value1:运算符'?'不能应用于类型'T'的操作数
为什么?
public interface IValueProvider<T>
{
T Value { get; }
}
class Validator<T>
{
public Validator(IValueProvider<T> provider)
{
_valueProvider = provider;
}
public T Value1 => _valueProvider?.Value ?? default(T);
public T Value2 => _valueProvider != null ? _valueProvider.Value : default(T);
private readonly IValueProvider<T> _valueProvider;
}
最佳答案
我相信问题在于编译器无法知道_valueProvider?.Value
表达式的类型。
让我们简化一下:
public interface IValueProvider<T>
{
T Value { get; }
}
public class Test
{
public static void Foo<T>(IValueProvider<T> provider)
{
var mystery = provider?.Value;
}
}
编译器应推断
mystery
的类型是什么?T
是引用类型或可为空的值类型,则表达式(因此mystery
)的类型为T
是有意义的。 T
是不可为空的值类型,则表达式(因此mystery
)的类型为T?
是有意义的。 由于没有对
T
进行约束,因此没有合适的类型可以使用,因此会出现(稍微不幸的)错误消息。如果该属性的类型为
string
,int
或int?
,那么所有这些都很好,并且表达式的类型分别为string
,int?
和int?
。但是T
却没有等效的方法。如果将
T
约束为引用类型,那很好,表达式的类型为T
:public static void Foo<T>(IValueProvider<T> provider) where T : class
{
// Variable is of type T
var mystery = provider?.Value;
}
如果将
T
约束为不可为空的值类型,则可以,并且表达式的类型为T?
(又名Nullable<T>
)。public static void Foo<T>(IValueProvider<T> provider) where T : struct
{
// Variable is of type Nullable<T>
var mystery = provider?.Value;
}
但是没有任何限制,就没有有效的翻译。
关于c# - 运算符 '?'不能应用于 'T'类型的操作数(2),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44174712/