2017-08-11 49 views
9

有没有更好的方法在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))); 

回答

11

你可以使用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}"); 
} 

周边的兼容性的详细信息等

+0

太好了,我不知道你能嵌入名字中的元素见feature document在这样的声明里面的元组中。 – gmn

+0

出于好奇,为什么不是匿名类型中的''A = x.A''? ''var x = new {A = x.A,B = x.B};'' –

+0

@RandRandom:这不是元组元素名称的语法。它在声明和元组文字中都是一致的':'。匿名类型更像是对象初始化器,“设置”属性(尽管类型实际上是不可变的)。 –

-1

Select需要2个类型参数:Select<TSource, TResult>。一个元组(int A, int B)只是一种类型,你也可以写它ValueTuple<int, int>。所以你必须,如果你想要一个名为元组

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