Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 运算符'';无法应用于类型为';T';(2)_C# - Fatal编程技术网

C# 运算符'';无法应用于类型为';T';(2)

C# 运算符'';无法应用于类型为';T';(2),c#,C#,我遇到了C#编译器(VS 2015)的一个奇怪行为。 在下面的代码中,编译器对Value2感到满意,但对Value1表示不满:运算符“?”不能应用于类型为“T”的操作数 为什么? 公共接口提供程序 { T值{get;} } 类验证器 { 公共验证器(IValueProvider提供程序) { _valueProvider=提供者; } 公共T值1=>_valueProvider?.Value??默认值(T); public T Value2=>\u valueProvider!=null?\u

我遇到了C#编译器(VS 2015)的一个奇怪行为。 在下面的代码中,编译器对Value2感到满意,但对Value1表示不满:运算符“?”不能应用于类型为“T”的操作数

为什么?

公共接口提供程序
{
T值{get;}
}
类验证器
{
公共验证器(IValueProvider提供程序)
{
_valueProvider=提供者;
}
公共T值1=>_valueProvider?.Value??默认值(T);
public T Value2=>\u valueProvider!=null?\u valueProvider.Value:默认值(T);
私有只读IValueProvider _valueProvider;
}

我认为问题在于编译器无法知道表达式的类型
\u valueProvider?.Value

让我们简化一下:

public interface IValueProvider<T>
{
    T Value { get; }
}

public class Test
{
    public static void Foo<T>(IValueProvider<T> provider)
    {
        var mystery = provider?.Value;
    }
}
如果将
T
约束为不可为空的值类型,则可以,并且表达式的类型为
T?
(也称为
nullable

publicstaticvoidfoo(IValueProvider提供程序),其中T:struct
{
//变量的类型为Nullable
var神秘=提供者?.Value;
}
但是如果没有这两个约束,就没有有效的翻译。

此代码:

public interface IValueProvider<T>
{
    T Value { get; }
}

public class Validator<T>
{
    public Validator(IValueProvider<T> provider)
    {
        var providerValue = provider?.Value;
    }
}
i、 e

这是不允许的,因为
int
不可为空


其余的错误都是从那里慢慢产生的。因此,将
T
约束为可空类型,例如
where T:class
,它将工作。

这并不奇怪<代码>?对于不可为空的类型(即结构)没有意义。如果没有类型约束,编译器不知道t是否为结构
Value2
在任何地方都不使用此运算符,这就是它工作的原因。@PanagiotisKanavos:但是
\U valueProvider
不是
t
类型,它是
IValueProvider
@CodeMaster类型。相反,它非常清楚,代码片段再现了问题。只需在LinqPad中尝试此操作,您就会立即发现问题。@CodeCaster此代码足以让其他人重现并理解错误。答案应该清楚地表明编译器错误与值有关,因为每个人都假设错误与值有关provider@CodeCaster:说实话,比实际需要多一点,但不是很多。这是一个绝对最小的例子吗?否。它是否足够接近以避免大量完全不相关的代码?绝对地它是完整的,允许问题真的很容易再现吗?是的。更简单地说,错误指的是
.Value
,而不是
提供者
。您在哪里看到“无法解除…”消息?@Henk VS2017 with ReSharper。
public static void Foo<T>(IValueProvider<T> provider) where T : class
{
    // Variable is of type T
    var mystery = provider?.Value;
}
public static void Foo<T>(IValueProvider<T> provider) where T : struct
{
    // Variable is of type Nullable<T>
    var mystery = provider?.Value;
}
public interface IValueProvider<T>
{
    T Value { get; }
}

public class Validator<T>
{
    public Validator(IValueProvider<T> provider)
    {
        var providerValue = provider?.Value;
    }
}
var providerValue = provider?.Value;
int providerValue = null;