【发布时间】:2017-09-19 19:34:32
【问题描述】:
我知道我可以在创建元组时隐式命名参数,例如:
var me = (age: 21, favoriteFood: "Custard");
是否可以在显式创建元组时命名参数?即
var me = new ValueTuple<int, string>(21, "Custard");
【问题讨论】:
我知道我可以在创建元组时隐式命名参数,例如:
var me = (age: 21, favoriteFood: "Custard");
是否可以在显式创建元组时命名参数?即
var me = new ValueTuple<int, string>(21, "Custard");
【问题讨论】:
不,你不能。 ValueTuple 类型实际上独立于 C# 中的命名字段支持。后者更像是匿名类型的命名属性。也就是说,编译器分析代码并根据您的声明和用法为适当的成员生成别名。编译器通过赋值来学习字段的名称。由于基本构造函数语法不提供命名字段的机制,因此您不能使用它直接生成具有命名字段的元组。
当然,您可以通过多种方式重新解释从构造函数语法返回的值,以将名称分配给该返回值。我假设您知道这种方法并且正在寻找更直接的方法。
作为我所说的“重新解释”的一个例子,你可以这样做:
static (int value, string text) ConvertToNamed((int, string) t) => t;
然后这将在新变量中命名字段:
var t1 = new ValueTuple<int, string>(21, "hello");
var t2 = ConvertToNamed(t1);
变量t1 被Item1 和Item2 卡住。但编译器会为变量t2隐式生成所需的名称。
也许一个更好的例子是你不需要额外的方法:
(int value, string text) t = new ValueTuple<int, string>(21, "hello");
同样,您并没有真正在构造函数语法中命名字段,而是通过局部变量声明重新解释它们。
这可能不是一个严重的限制。在希望有一个持久的、易于分配的名称的情况下,声明一个用户定义的类型可能比使用元组语法更好。您也可以为用户定义的类型编写解构器,并且声明这样的类型意味着名称是反射时的一等公民,dynamic 等。
【讨论】:
(int value, string text) ConvertToNamed((int value, string text) t) 而不仅仅是(int value, string text) ConvertToNamed((int, string) t)?
您可以在赋值期间强制转换为命名元组:
var me = ((int value, string text)) new ValueTuple<int, string>(21, "Custard");
【讨论】:
(age: 21, favoriteFood: "Custard")(即实现相同目的的通常、自然的方式)。
_dbContext.Products .Where(p=>p.Id == productId) .Join(ProductDetails, p=>p.Id, pd=>pd.Id, (p, pd) =>((Product Product, ProductDetail Detail)) new ValueTuple<Product, Detail>(p, pd)) .ProjectTo<ProductWithDetailsDTO>(_mapper.ConfigurationProvider).ToListAsync(cancellationToken); 实际上,除了那个之外,我没有找到将 2 个连接表映射到 1 个 DTO 的工作方法。
在 Linq 中使用 ValueTuple 时正在寻找这个。我做了一个 F2-rename 变量,它创建了以下语法:
var query = from x in myList
select (First: x.something, Second: x.other) into g
select new Whatever(g.First, g.Second);
【讨论】:
我不相信。以下是我在 ValueTuple 上找到的文档:
https://docs.microsoft.com/en-us/dotnet/api/system.valuetuple-7?view=netframework-4.7
我个人没有使用过 ValueTuble 类型。我以前使用过 Tuple 类是这样的:
var tuple = new Tuple<int, string>(21, "Custard");
var number = tuple.Item1;
var st = tuple.Item2;
但是我发现使用元组,特别是当通过方法传递时很笨重。总是必须知道 Item1 和 Item2 等中的内容。根据 ValueTuple 文档,它的使用方式相同。
你不应该只做一个实体类吗?
我使用了我认为适合您需要的匿名类型。
var anyom = new
{
age = 21,
favoriteFood = "Custard"
};
number = anyom.age;
st = anyom.favoriteFood;
【讨论】:
ValueTuple structs时有特殊的行为,但类型本身有Item1、Item2等,就像Tuple类有属性一样。