元组类中的命名比“Item1”、“Item2”更好
有没有办法使用 Tuple 类,但提供其中项目的名称?
例如:
public Tuple<int, int, int int> GetOrderRelatedIds()
返回 OrderGroupId、OrderTypeId、OrderSubTypeId 和 OrderRequirementId 的 id。
如果能让我的方法的用户知道哪个是哪个,那就太好了。 (当你调用该方法时,结果是 result.Item1、result.Item2、result.Item3、result.Item4。目前尚不清楚哪个是哪个。)
(我知道我可以创建一个类来保存所有这些 Id ,但如果这些 Id 已经有自己的类,那么为这个方法的返回值创建一个类似乎很愚蠢。)
Is there a way to use a Tuple class, but supply the names of the items in it?
For example:
public Tuple<int, int, int int> GetOrderRelatedIds()
That returns the ids for OrderGroupId, OrderTypeId, OrderSubTypeId and OrderRequirementId.
It would be nice to let the users of my method know which is which. (When you call the method, the results are result.Item1, result.Item2, result.Item3, result.Item4. It is not clear which one is which.)
(I know I could just create a class to hold all these Ids, but it these Ids already have their own classes they live in and making a class for this one method's return value seems silly.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
在 C# 7.0 (Visual Studio 2017) 中,有一个新的构造可以做到这一点:
In C# 7.0 (Visual Studio 2017) there is a new construction to do that:
在 C# 7.0 之前,除了定义自己的类型之外,没有其他方法可以做到这一点。
Up to C# 7.0, there was no way to do this short of defining your own type.
复制我在这篇帖子中的答案,因为它更适合这里。
从 C# v7.0 开始,现在可以命名元组属性,之前默认使用
Item1
、Item2
等名称。命名元组文字的属性:
控制台上的输出:
从方法返回元组(具有命名属性):
控制台上的输出:
创建元组列表具有命名属性
控制台输出:
注意:本文中的代码片段使用 C# v6 的字符串插值功能,详细信息 此处。
Reproducing my answer from this post as it is a better fit here.
Starting C# v7.0, it is now possible to name the tuple properties which earlier used to default to names like
Item1
,Item2
and so on.Naming the properties of Tuple Literals:
The output on console:
Returning Tuple (having named properties) from a method:
The output on console:
Creating a list of Tuples having named properties
Output on console:
Note: Code snippets in this post are using string interpolation feature of C# v6 as detailed here.
这是您所问问题的一个过于复杂的版本:
为什么不直接制作一个类?
Here is an overly complicated version of what you are asking:
Why not just make a class?
TL:DR->
System.ValueTuple
可以具有自定义字段名称,而System.Tuple
则不能。澄清一下,C# 7.0 及更高版本中有 2 种不同类型的元组。在此之前,只有 1 种单一类型的元组可用。
System.Tuple (这是C# 7 之前存在的元组的原始类型)
和
System.ValueTuple(元组类型已在 C# 中添加 7)
当您通过
Tuple<...>
类声明一个元组时:您正在声明一个
元组
对象数据类型。当您通过括号声明元组时:
您正在声明
ValueTuple
value 数据类型。每一种的功能和行为都不同。在您的问题中,您的方法返回一个 System.Tuple 对象。
不幸的是,通过 System.Tuple 类创建的 Tuple 对象没有内置功能来为每个属性提供自定义名称。它们始终默认为 ItemN,具体取决于它们包含的属性数量。
另一方面,
System.ValueTuple
值可以包含自定义命名字段。有关更多信息,您可以参考 元组类型(C# 参考) 和/或上面每个类的链接。但本质上,文档强调的两种不同类型元组的一些主要区别是:
因此,如果您的方法需要返回 System.Tuple 对象或者您更希望该类型对象的行为,那么在编写本文时,您将无法实现您想要的。但是,如果您的方法可以返回 System.ValueTuple 值,那么您可以在返回值中为其提供自定义命名字段。
TL:DR ->
System.ValueTuple
s can have custom names for fields,System.Tuple
s cannot.Just to clarify, there are 2 different types of tuples in C# 7.0 and later. Before that there was only 1 single type of tuple available.
System.Tuple (this is the original type of tuple that existed pre C# 7)
and
System.ValueTuple (tuple type that was added in C# 7)
When you declare a tuple via the
Tuple<...>
class:You're declaring a
Tuple
object data type.When you declare a tuple via parenthesis:
You're declaring a
ValueTuple
value data type.Each one functions and behaves differently. In your question, your method returns a
System.Tuple
object.Unfortunately, Tuple objects created via the
System.Tuple
class have no built in functionality to give each property a custom name. They always default to ItemN depending on how many properties they contain.System.ValueTuple
values on the other hand can contain custom named fields.For more info, you can refer to Tuple types (C# reference) and/or the links to each class above. But essentially some of the key differences of the 2 different types of tuples that the documentation highlights are:
So if your method needs to return a
System.Tuple
object or you desire the behavior of that type of object more, then as of writing this, you can't achieve what you want. However, if your method can return aSystem.ValueTuple
value, then you can give it custom named fields in the returned value.使用.net 4,您也许可以查看
ExpandoObject<但是,不要将它用于这种简单的情况,因为编译时错误会变成运行时错误。
其他值得一提的是方法内的匿名类型 ,但是如果你想返回它,你需要创建一个类。
With .net 4 you could perhaps look at the
ExpandoObject
, however, don't use it for this simple case as what would have been compile-time errors become run-time errors.Something else worth mentioning is an anonymous type for within a method, but you need to create a class if you want to return it.
MichaelMocko 回答得很好,
但我想添加一些我必须在
上面弄清楚的事情,如果您使用 .net Framework ,Line 会给您编译时错误 4.7
因此,如果您有一个使用 .net 框架的项目 4.7 并且您仍然想使用 ValueTuple,而不是安装 this NuGet 包
更新:
从方法返回命名元组并使用它的示例
使用它
MichaelMocko Answered is great,
but I want to add a few things which I had to figure out
above Line will give you compile-time error if you are using .net framework < 4.7
So if you have a project that is using .net framework < 4.7 and still you want to use ValueTuple than workAround would be installing this NuGet package
Update:
Example of returning Named tuple from a method and using it
Using it
只是添加到 @MichaelMocko 答案。元组目前有几个问题:
您不能在 EF 表达式树中使用它们
示例:
这将无法编译,并出现“表达式树可能不包含元组文字”错误。不幸的是,当将元组添加到语言中时,表达式树 API 并未扩展对元组的支持。
跟踪(并投票)此问题的更新:https://github.com/dotnet/roslyn/ issues/12897
要解决这个问题,您可以先将其转换为匿名类型,然后将值转换为元组:
另一种选择是使用 ValueTuple.Create:
引用:
https://www.damirscorner.com/blog/posts/20181207-NoSupportForTuplesInExpressionTrees.html
<一href="https://stackoverflow.com/questions/43400071/convert-anonymous-type-to-new-c-sharp-7-tuple-type">将匿名类型转换为新的 C# 7 元组类型< /p>
你不能在 lambda 中解构它们
有一个添加支持的建议:https://github.com/dotnet/csharplang/issues/258
示例:
参考文献:
它们不会很好地序列化
元组字段名称仅在编译时可用,并在运行时完全消失。
参考文献:
Just to add to @MichaelMocko answer. Tuples have couple of gotchas at the moment:
You can't use them in EF expression trees
Example:
This will fail to compile with "An expression tree may not contain a tuple literal" error. Unfortunately, the expression trees API wasn't expanded with support for tuples when these were added to the language.
Track (and upvote) this issue for the updates: https://github.com/dotnet/roslyn/issues/12897
To get around the problem, you can cast it to anonymous type first and then convert the value to tuple:
Another option is to use ValueTuple.Create:
References:
https://www.damirscorner.com/blog/posts/20181207-NoSupportForTuplesInExpressionTrees.html
Convert anonymous type to new C# 7 tuple type
You can't deconstruct them in lambdas
There's a proposal to add the support: https://github.com/dotnet/csharplang/issues/258
Example:
References:
They won't serialize nicely
Tuple field names are only available at compile time and are completely wiped out at runtime.
References:
到今天为止,事情就这么简单。 使用 this代替 Tuple 关键字
。
获取这样的值。
As of today, it's this simple. Instead of using the Tuple keyword
Use this.
Get the values like this.
不,您不能命名元组成员。
中间的方法是使用 ExpandoObject 而不是元组。
No, you can't name the tuple members.
The in-between would be to use ExpandoObject instead of Tuple.
如果你的物品类型都不同,这里是我制作的一个类,可以更直观地获取它们。
该类的用法:
源码:
If the types of your items are all different, here is a class I made to get them more intuitively.
The usage of this class:
Source code:
来自文档: https://learn .microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-tuples
From Docs: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-tuples
这非常烦人,我希望 C# 的未来版本能够满足这一需求。我发现最简单的解决方法是使用不同的数据结构类型或重命名“项目”,以保证您和其他人阅读您的代码的理智。
This is very annoying and I expect future versions of C# will address this need. I find the easiest work around to be either use a different data structure type or rename the "items" for your sanity and for the sanity of others reading your code.
为什么不使用多重返回而不是使用元组
Why not using a multiple returns instead of using tuple
我想我会创建一个类,但另一种选择是输出参数。
由于您的元组仅包含整数,因此您可以使用
Dictionary
表示它,但我也不建议这样做。
I think I would create a class but another alternative is output parameters.
Since your Tuple only contains integers you could represent it with a
Dictionary<string,int>
but I don't recommend that either.
为什么每个人都让生活如此艰难。元组用于临时数据处理。一直使用元组会使代码在某些时候变得非常难以理解。为所有创建类最终可能会使您的项目变得臃肿。
然而,这是关于平衡的......
你的问题似乎是你想要上课的问题。为了完整起见,下面的类还包含构造函数。
的正确模式
或者,如果您想要非常简单:您还可以使用类型初始值设定项:
Why is everyone making life so hard. Tuples are for rather temporary data processing. Working with Tuples all the time will make the code very hard to understand at some point. Creating classes for everything could eventually bloat your project.
It's about balance, however...
Your problem seems to be something you would want a class for. And just for the sake of completeness, this class below also contains constructors.
This is the proper pattern for
Or, if you want it really simple: You can also use type initializers:
我会在摘要中写下项目名称。
因此,将鼠标悬停在函数 helloworld() 上,文本将显示 hello = Item1 和 world = Item2
I would write the Item names in the summay..
so by hovering over the function helloworld() the text will say hello = Item1 and world = Item2
嘿,如果您在删除命名元组参数时遇到动态或对象转换问题,只需创建一个函数,通过引用传递动态/对象转换指针并在返回时重新转换它......让这个坏男孩工作......
Hey if you wind up having issues with the Dynamic or Object casting removing your Named Tuple parameters, just create a function that passes the dynamic/object cast pointer by reference and recasts it upon return...got this bad-boy working...
如果您需要一个小类来存储数据(而不是像 ValueTuple 这样的结构),那么从 C# 9 开始,您可以使用 record 而不是 Tuple 类
例如:
If you need a small class to store data (not a structure like ValueTuple), then starting from C# 9 you can use record instead of the Tuple class
For example:
您可以编写一个包含元组的类。
您需要重写 Equals 和 GetHashCode 函数
以及 == 和 != 运算符。
将返回:
True
True
You Can write a class that contains the Tuple.
You need to override the Equals and GetHashCode functions
and the == and != operators.
will return:
True
True
C# 7 元组示例
C# 7 tuple example