我喜欢在pattern-matching上使用nullable int,即int?
int t = 42;
object tobj = t;
if (tobj is int? i)
{
System.Console.WriteLine($"It is a nullable int of value {i}");
}但是,这会导致以下语法错误:
‘i’是用红色的线条标记的。
该表达式在使用旧运算符is时进行编译。
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进行测试)
我以为这和操作符的优先级有关。因此,我尝试在几个地方使用括号,但这没有帮助。
为什么会出现这些语法错误,以及如何避免它们?
发布于 2018-01-19 15:33:35
x is T y,case T y等多种形式的类型模式,null。这是因为没有一个类型,所以问“这是这种类型的null吗?”是个毫无意义的问题。
因此,t is int? i或t is Nullable<int> i作为模式没有任何意义:要么t是一个int,在这种情况下t is int i无论如何都会匹配,要么是null,在这种情况下,没有一个类型模式可以导致匹配。
这就是为什么编译器不支持t is int? i或t is Nullable<int> i,而且可能永远也不会支持的原因。
在使用t is int? i时,您从编译器获得额外错误的原因是,例如,t is int? "it's an int" : "no int here"是有效的语法,因此编译器对在此上下文中使用?进行可空类型的尝试感到困惑。
至于如何避免它们,显而易见的答案(虽然可能不是很有用)是:不要使用可空类型作为类型模式中的类型。一个更有用的答案需要你解释你为什么要这么做。
发布于 2019-08-10 06:02:22
对于任何想知道如何实际使用模式匹配和空标签的人,您可以使用泛型助手函数这样做,如下所示:
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,但这可能是一个巨大的代价,而不是像平常一样的空检查。
知道了这一点,这里有一个更好的功能:
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;
}https://stackoverflow.com/questions/48342949
复制相似问题