我不理解C#7中var
模式的用例。 MSDN:
与
var
模式匹配的模式总是成功的。它的语法是
expr is var varname
其中expr的值始终分配给名为
varname
的局部变量。varname
是一个与expr
相同类型的静态变量。
在我看来,MSDN上的例子是无用的,特别是因为if
是多余的:
object[] items = { new Book("The Tempest"), new Person("John") };
foreach (var item in items) {
if (item is var obj)
Console.WriteLine($"Type: {obj.GetType().Name}, Value: {obj}");
}
在这里我没有看到任何好处,如果你直接访问循环变量item
,也可以使用相同的Object
类型。 if
也令人困惑,因为它永远不会是false
。
我可以使用qazxsw poi或直接使用qazxsw poi。有人可以更好地解释用例吗?
变量模式在var otherItem = item
中经常被讨论,因为它的用例并不完全清楚,并且考虑到item
在C# language repository没有执行空检查的事实,使得它看起来相当无用。
但是,它实际上并不打算用作is var x
。它意味着当左侧不是变量本身时使用。
以下是is T x
的一些例子。它们都使用了不在C#中的功能,但这只是表明var模式的引入主要是为了准备这些东西,所以他们以后不必再触摸它。
下面的示例声明了一个函数obj is var x
,用于在表达式树上使用结构模式匹配来构造函数的the specification:
Deriv
这里,the derivative图案可以在结构内部使用,以从结构中“拉出”元素。同样,以下示例简化了表达式:
Expr Deriv(Expr e)
{
switch (e) {
// …
case Const(_): return Const(0);
case Add(var Left, var Right):
return Add(Deriv(Left), Deriv(Right));
// …
}
作为var
,这个想法也是为了进行属性模式匹配,允许以下内容:
Expr Simplify(Expr e)
{
switch (e) {
case Mult(Const(0), _): return Const(0);
// …
case Add(Const(0), var x): return Simplify(x);
}
}
没有检查Github上的设计说明,我猜这是为了与gafter writes here的一致性增加更多,并作为更先进的模式匹配案例的垫脚石,
从原来的if (o is Point {X is 3, Y is var y})
{ … }
帖子:
形式var x的var模式(其中x是标识符),它总是匹配,并简单地将输入的值放入与输入相同类型的新变量x中。
谢尔盖·特普利亚科夫最近的switch
:
如果你知道究竟发生了什么,你会发现这种模式很有用。它可用于在表达式中引入临时变量:此模式实际上使用对象的实际类型创建临时变量。
What’s New in C# 7.0
该片段之前的警告也很重要:
目前尚不清楚为什么仅在发布模式下行为不同。但我认为所有问题都属于同一个问题:该功能的初始实现不是最理想的。但根据Neal Gafter的评论,这将改变:“模式匹配降低代码正在从头开始重写(以支持递归模式)。我希望你在这里寻求的大多数改进都将来自” “在新的代码中。但在重写准备好黄金时间之前还需要一段时间。”
优点是用var关键字声明的变量是对象的真实类型,
我唯一可以想到的就是你发现你已经写了两个相同的代码块(比如一个public void VarPattern(IEnumerable<string> s)
{
if (s.FirstOrDefault(o => o != null) is var v
&& int.TryParse(v, out var n))
{
Console.WriteLine(n);
}
}
),一个用于Christian Nagel,另一个用于switch
。
您可以通过切换到expr is object a
来组合块。
它也可能在代码生成场景中很有用,在这种场景中,无论出于何种原因,您已经将自己写入角落并且总是期望生成模式匹配但现在想要发出“匹配所有”模式。
在大多数情况下确实如此,var模式的好处并不明确,甚至可能是一个坏主意。但是,作为捕获临时变量中的匿名类型的一种方法,它非常有效。希望这个例子可以说明这一点:注意下面,添加一个null case避免var永远为null,并且不需要null检查。
expr is null