首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么可空的模式匹配会导致语法错误?

为什么可空的模式匹配会导致语法错误?
EN

Stack Overflow用户
提问于 2018-01-19 14:09:46
回答 2查看 6.1K关注 0票数 32

我喜欢在pattern-matching上使用nullable int,即int?

代码语言:javascript
复制
int t  = 42;
object tobj = t;    
if (tobj is int? i)
{
    System.Console.WriteLine($"It is a nullable int of value {i}");
}

但是,这会导致以下语法错误:

‘i’是用红色的线条标记的。

该表达式在使用旧运算符is时进行编译。

代码语言:javascript
复制
int t = 42;
object tobj = t;    
if (tobj is int?)
{
    System.Console.WriteLine($"It is a nullable int");
}


string t = "fourty two";
object tobj = t;
if (tobj is string s)
{
    System.Console.WriteLine($@"It is a string of value ""{s}"".");
}

也能像预期的那样工作。

(我正在使用/问题/加标签/c%23-7.2,并使用/问题/加标签/..net 4.7.1/问题/加标签/..net 4.6.1进行测试)

我以为这和操作符的优先级有关。因此,我尝试在几个地方使用括号,但这没有帮助。

为什么会出现这些语法错误,以及如何避免它们?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-19 15:33:35

x is T ycase T y等多种形式的类型模式,null。这是因为没有一个类型,所以问“这是这种类型的null吗?”是个毫无意义的问题。

因此,t is int? it is Nullable<int> i作为模式没有任何意义:要么t是一个int,在这种情况下t is int i无论如何都会匹配,要么是null,在这种情况下,没有一个类型模式可以导致匹配。

这就是为什么编译器不支持t is int? it is Nullable<int> i,而且可能永远也不会支持的原因。

在使用t is int? i时,您从编译器获得额外错误的原因是,例如,t is int? "it's an int" : "no int here"是有效的语法,因此编译器对在此上下文中使用?进行可空类型的尝试感到困惑。

至于如何避免它们,显而易见的答案(虽然可能不是很有用)是:不要使用可空类型作为类型模式中的类型。一个更有用的答案需要你解释你为什么要这么做。

票数 39
EN

Stack Overflow用户

发布于 2019-08-10 06:02:22

对于任何想知道如何实际使用模式匹配和空标签的人,您可以使用泛型助手函数这样做,如下所示:

代码语言:javascript
复制
public static bool TryConvert<T>(object input, out T output)
{
    if (input is T result)
    {
        output = result;
        return true;
    }
    output = default(T);
    // Check if input is null and T is a nullable type.
    return input == null && System.Nullable.GetUnderlyingType(typeof(T)) != null;
}

如果true是与input包含的类型相同的可空或不可空的,或者如果input为null且T为可空,则将返回input。基本上和正常工作一样,但也处理空值。

附带注意:有趣的是,从我的测试中,我发现每次调用T时,System.Nullable.GetUnderlyingType(typeof(T))都会分配40字节的垃圾。不知道为什么,在我看来好像是个bug,但这可能是一个巨大的代价,而不是像平常一样的空检查。

知道了这一点,这里有一个更好的功能:

代码语言:javascript
复制
public static bool TryConvert<T>(object input, out T? output) where T : struct
{
    if (input is T result)
    {
        output = result;
        return true;
    }
    output = default(T?);
    return input == null;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48342949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档