类型'<null>'

时间:2019-04-23 23:42:36

标签: c# c#-7.0 visual-studio-2019 c#-8.0 c#-7.3

这里是最小样本:

class C {
  public bool F<T>(T x) => x is null;
}

引起问题的实际代码在https://github.com/kofifus/With/blob/master/With.cs#L35

直到今天,这种编译效果还不错,但我刚刚升级到

  

Microsoft Visual Studio Community 2019预览版本16.1.0预览   2.0

代码现在出现以下错误:

Error CS8511 An expression of type 'T' cannot be handled by a pattern of type '<null>'. Please use language version 'preview' or greater to match an open type with a constant pattern.

这是怎么回事?解决此问题的正确方法是什么?

note1-我不希望使用C#语言预览ATM
note2-如果将x is null更改为x==null

,它仍然可以编译

2 个答案:

答案 0 :(得分:4)

除了提到的解决方案外,它曾经为您服务is likely to be caused by a bug in the 2019 preview

  

但是,在Visual Studio 2019中,我们不正确地允许它以7.0、7.1、7.2和7.3语言版本进行编译。在Visual Studio 2019 Update 1中,我们将使其错误(与在Visual Studio 2017中一样),并建议更新为预览版或8.0。

似乎允许在开放的泛型中使用is null 将成为C#8的一部分,并且是championed here。错误发布后,很可能最终tell you to upgrade to C#8(而不是“预览”)。

答案 1 :(得分:1)

我非常怀疑您的说法是否一直有效。

更新

如果它在以前的 preview 中可以正常工作,则可能是由于语言功能被丢弃

可能您正在尝试与null进行比较,即==

public bool F<T>(T x) => x == null;

但是,更通用的检查泛型是否相等的方法是使用EqualityComparer<T>.Default。这尊重IEquatable<T>,没有装箱,也尊重object.Equals,并处理所有Nullable<T> nullable 类型

的细微差别。
public bool F<T>(T x) => EqualityComparer<T>.Default.Equals(x, default(T));

Update

仅作记录,{as you can see here

public bool F<T>(T x) => !(x is object);

基本上只是编译为

public bool F<T>(T x)
{
    return x == null;
}

相同
public bool F<T>(T x) => x == null;