C#7 中的变量模式有什么好处?



我不了解C#7中var模式的用例。MSDN:

var模式的模式匹配总是成功的。它的语法是

expr is var varname

expr的值始终分配给命名的本地变量 varnamevarname是与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

我可以使用 var otherItem = item或三连通使用item。有人可以更好地解释用例吗?

var模式在C#语言存储库中经常讨论,鉴于其用例不清楚,并且鉴于is var x不执行的事实是什么is T x时进行的无效检查,使其看起来毫无用处。

但是,它实际上并不是要用作obj is var x。当左手侧是不是的变量时,它是在使用。

这是规范中的一些示例。他们都使用不在c#中的功能 ,但这只是表明var模式的引入是为了为这些东西做准备的,因此他们以后不必再触摸它。<<<<<<<<<<<<<<<</p>

以下示例声明函数 Deriv,以使用在表达树上匹配的结构模式构造函数的导数:

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);
    }
}

正如Gafter在这里所写的那样,这个想法也应具有属性模式匹配,允许以下内容:

if (o is Point {X is 3, Y is var y})
{ … }

未在GitHub上检查设计笔记,我猜想这是与switch的一致性添加的,并且是用于更高级的图案匹配案例的垫脚石,

来自原始内容,C#7.0帖子中的新事物:

var x的var模式(其中x是标识符(,它始终匹配,然后将输入的值放入具有与输入相同类型的新鲜变量x中。

和Sergey Teplyakov最近的解剖帖子:

如果您知道到底发生了什么,则可能会发现这种模式有用。它可用于在表达式中引入临时变量: 这种模式实质上使用对象的实际类型创建了临时变量。

public void VarPattern(IEnumerable<string> s)
{
    if (s.FirstOrDefault(o => o != null) is var v
        && int.TryParse(v, out var n))
    {
        Console.WriteLine(n);
    }
}

该片段之前的警告righ也很重要:

尚不清楚为什么仅在发布模式下行为有所不同。但是我认为所有问题都属于同一水桶:该功能的初始实现是次优的。但是,基于Neal Gafter的这一评论,这将会改变:"模式匹配的降低代码也从头开始重写(也支持递归模式(。我希望您在这里寻求的大多数改进将获得"免费"在新的代码中。但是要在黄金时段准备好重写还需要一段时间。

根据克里斯蒂安·纳格尔(Christian Nagel(:

优点是用var关键字声明的变量是对象的真实类型的

我唯一能想到的是,如果您发现已经写了两个相同的代码块(例如,一个switch(,一个用于expr is object a,另一个用于expr is null。/p>

您可以通过切换到expr is var a

组合块。

它在代码生成方案中也可能很有用,无论出于何种原因,您已经将自己写入角落,并始终期望生成模式匹配,但现在想发布"匹配"模式。

在大多数情况下是真的,var模式的好处尚不清楚,甚至可能是个坏主意。但是,作为在温度变量中捕获匿名类型的一种方式,它效果很好。希望这个示例可以说明这一点:请注意,添加无效的情况避免了var以为null,并且不需要零检查。

        var sample = new(int id, string name, int age)[] { 
                                                          (1, "jonas", 50),                                                                                                                            
                                                          (2, "frank", 48) };
        var f48 = from s in sample 
                  where s.age == 48 
                  select new { Name = s.name, Age = s.age };
        switch(f48.FirstOrDefault())
        {
            case var choosen when choosen.Name == "frank":
                WriteLine(choosen.Age);
                break;
            case null:
                WriteLine("not found");
                break;
        }

最新更新