【问题标题】:Using named tuples in select statements在选择语句中使用命名元组
【发布时间】:2018-01-19 18:27:10
【问题描述】:

有没有更好的方法在 C# 7 中使用 var 目标变量来选择命名元组?我在示例 1 中一定做错了什么,或者完全误解了某些东西。我似乎必须明确设置目标类型才能做到这一点。

//1. Fails to compile with "incorrect number of type parameters" issue.
var tuples = source.Select<(int A, int B)>(x => (x.A, x.B));

//2. Compiles
IEnumerable<(int A, int B)> tuples = toCheck.Select(x => (x.A, x.B));

//3. Compiles
var tuples = new HashSet<(int A, int B)>(source.Select(x => (x.A, x.B)));

【问题讨论】:

    标签: c# generics tuples c#-7.0


    【解决方案1】:

    您可以只使用var,但您需要确保元组元素是实际命名的。

    在 C# 7.0 中,您需要明确地执行此操作:

    var tuples = source.Select(x => (A: x.A, B: x.B));
    foreach (var tuple in tuples)
    {
        Console.WriteLine($"{tuple.A} / {tuple.B}");
    }
    

    在 C# 7.1 中,当从属性或字段获取元组文字中的值时,该标识符将隐含地成为元素名称,因此您将能够编写:

    var tuples = source.Select(x => (x.A, x.B));
    foreach (var tuple in tuples)
    {
        Console.WriteLine($"{tuple.A} / {tuple.B}");
    }
    

    有关兼容性等的更多详细信息,请参阅feature document

    【讨论】:

    • 太好了,我没有意识到你可以像这样在声明中嵌入元组中元素的名称。
    • 出于好奇,为什么A= x.A 不像匿名类型那样? var x = new { A = x.A, B = x.B };
    • @RandRandom:这不是元组元素名称的语法。在声明和元组文字中,它始终是:。匿名类型更像是对象初始化器,“设置”属性(尽管这些类型实际上是不可变的)
    • That's just not the syntax for tuple element names. 这是我的问题,为什么他们不使用相同的语法?看起来很奇怪,因为它 feels 类似,对于像我这样不知道背后魔力的开发者来说。
    • @RandRandom:忽略我对声明的看法。但它用于提供参数名称的相同语法。就我个人而言,我可以接受 - 如果有的话,我想如果匿名类型使用冒号,我会更喜欢它。
    【解决方案2】:

    Select 采用 2 个类型参数:Select&lt;TSource, TResult&gt;。元组(int A, int B) 只是一种类型,你也可以写成ValueTuple&lt;int, int&gt;。所以如果你想要一个命名元组,你必须写两个参数

    var tuples = source.Select<TypeOfSource, (int A, int B)>(x => (x.A, x.B));
    

    【讨论】:

      猜你喜欢
      • 2021-04-28
      • 2011-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-07
      • 1970-01-01
      • 1970-01-01
      • 2017-02-20
      相关资源
      最近更新 更多