Vac*_*ano 180 c# tuples c#-4.0
有没有办法使用Tuple类,但提供其中的项目名称?
例如:
public Tuple<int, int, int int> GetOrderRelatedIds()
Run Code Online (Sandbox Code Playgroud)
返回OrderGroupId,OrderTypeId,OrderSubTypeId和OrderRequirementId的id.
让我的方法的用户知道哪个是哪个是很好的.(当你调用方法时,结果是result.Item1,result.Item2,result.Item3,result.Item4.不清楚哪一个是哪个.)
(我知道我可以创建一个类来保存所有这些ID,但是这些ID已经拥有了他们自己的类,并为这个方法的返回值创建一个类看起来很傻.)
Mic*_*cko 240
在C#7.0(Visual Studio 2017)中,有一个新的结构可以做到这一点:
(string first, string middle, string last) LookupName(long id)
Run Code Online (Sandbox Code Playgroud)
Mar*_*lug 52
直到C#7.0,没有办法做到这一点,无法定义自己的类型.
sco*_*ttm 32
这是你要问的过于复杂的版本:
class MyTuple : Tuple<int, int>
{
public MyTuple(int one, int two)
:base(one, two)
{
}
public int OrderGroupId { get{ return this.Item1; } }
public int OrderTypeId { get{ return this.Item2; } }
}
Run Code Online (Sandbox Code Playgroud)
为什么不上课?
Sna*_*nap 23
TL:DR -> System.ValueTuples 可以为字段指定自定义名称,而System.Tuples 则不能。
澄清一下,C# 7.0 及更高版本中有 2 种不同类型的元组。在此之前,只有 1 种单一类型的元组可用。
System.Tuple(这是 C# 7 之前存在的元组的原始类型)和 System.ValueTuple(C# 7 中添加的元组类型)
当您通过类声明元Tuple<...>组时:
public Tuple<int, string, int> GetUserInfo();
Run Code Online (Sandbox Code Playgroud)
您正在声明对象数据类型。Tuple
当您通过括号声明元组时:
public (int id, string name, int age) GetUserInfo();
Run Code Online (Sandbox Code Playgroud)
您正在声明一个值数据类型。ValueTuple
每一种的功能和行为都不同。在你的问题中,你的方法返回一个System.Tuple对象。
不幸的是,通过类创建的 Tuple 对象System.Tuple没有内置功能来为每个属性提供自定义名称。它们始终默认为 Item N,具体取决于它们包含的属性数量。
System.ValueTuple另一方面,值可以包含自定义命名字段。
有关更多信息,您可以参考元组类型(C# 参考)和/或上面每个类的链接。但本质上,文档强调的两种不同类型元组的一些主要区别是:
由类型支持的 C# 元组
System.ValueTuple与由类型表示的元组不同System.Tuple。主要区别如下:
System.ValueTuple类型是值类型。System.Tuple类型是引用类型。System.ValueTuple类型是可变的。System.Tuple类型是不可变的。- 类型的数据成员
System.ValueTuple是字段。类型的数据成员System.Tuple是属性。
因此,如果您的方法需要返回一个System.Tuple对象,或者您更希望该类型对象的行为,那么在编写本文时,您将无法实现您想要的。但是,如果您的方法可以返回一个System.ValueTuple值,那么您可以在返回值中为其指定自定义命名字段。
Geo*_*ett 12
使用.net 4,您可以查看ExpandoObject,但是,不要将它用于这个简单的情况,因为编译时错误会成为运行时错误.
class Program
{
static void Main(string[] args)
{
dynamic employee, manager;
employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
manager = new ExpandoObject();
manager.Name = "Allison Brown";
manager.Age = 42;
manager.TeamSize = 10;
WritePerson(manager);
WritePerson(employee);
}
private static void WritePerson(dynamic person)
{
Console.WriteLine("{0} is {1} years old.",
person.Name, person.Age);
// The following statement causes an exception
// if you pass the employee object.
// Console.WriteLine("Manages {0} people", person.TeamSize);
}
}
// This code example produces the following output:
// John Smith is 33 years old.
// Allison Brown is 42 years old.
Run Code Online (Sandbox Code Playgroud)
别的东西值得一提的是匿名类型 的方法中,但你需要创建一个类,如果你想退货.
var MyStuff = new
{
PropertyName1 = 10,
PropertyName2 = "string data",
PropertyName3 = new ComplexType()
};
Run Code Online (Sandbox Code Playgroud)
MichaelMocko 回答很棒,
但我想添加一些我必须弄清楚的事情
(string first, string middle, string last) LookupName(long id)
Run Code Online (Sandbox Code Playgroud)
如果您使用的是.net framework < 4.7,上面的行会给您编译时错误
因此,如果您有一个使用.net framework < 4.7的项目,并且您仍然想使用 ValueTuple,那么 workAround 将安装此NuGet 包
更新:
从方法返回命名元组并使用它的示例
public static (string extension, string fileName) GetFile()
{
return ("png", "test");
}
Run Code Online (Sandbox Code Playgroud)
使用它
var (extension, fileName) = GetFile();
Console.WriteLine(extension);
Console.WriteLine(fileName);
Run Code Online (Sandbox Code Playgroud)
从本文中转载我的答案,因为这里比较合适。
启动C#7.0版现在可以命名较早使用默认名称类似的元组的属性Item1,Item2等等。
命名元组文字的属性:
var myDetails = (MyName: "RBT_Yoga", MyAge: 22, MyFavoriteFood: "Dosa");
Console.WriteLine($"Name - {myDetails.MyName}, Age - {myDetails.MyAge}, Passion - {myDetails.MyFavoriteFood}");
Run Code Online (Sandbox Code Playgroud)
控制台上的输出:
名字-RBT_Yoga,年龄-22,激情-Dosa
从方法返回元组(具有命名属性):
static void Main(string[] args)
{
var empInfo = GetEmpInfo();
Console.WriteLine($"Employee Details: {empInfo.firstName}, {empInfo.lastName}, {empInfo.computerName}, {empInfo.Salary}");
}
static (string firstName, string lastName, string computerName, int Salary) GetEmpInfo()
{
//This is hardcoded just for the demonstration. Ideally this data might be coming from some DB or web service call
return ("Rasik", "Bihari", "Rasik-PC", 1000);
}
Run Code Online (Sandbox Code Playgroud)
控制台上的输出:
员工详细信息:Rasik,Bihari,Rasik-PC,1000
创建具有命名属性的元组列表
var tupleList = new List<(int Index, string Name)>
{
(1, "cow"),
(5, "chickens"),
(1, "airplane")
};
foreach (var tuple in tupleList)
Console.WriteLine($"{tuple.Index} - {tuple.Name}");
Run Code Online (Sandbox Code Playgroud)
在控制台上输出:
1-牛5-鸡1-飞机
我希望我已经涵盖了所有内容。如果有任何我想念的东西,请在评论中给我反馈。
注意:我的代码段使用的是C#v7的字符串插值功能,如此处所述。
只是添加到 @MichaelMocko 答案。元组目前有几个问题:
例子:
public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
return ctx.Persons
.Where(person => person.Id == id)
// Selecting as Tuple
.Select(person => (person.Name, person.Surname))
.First();
}
Run Code Online (Sandbox Code Playgroud)
这将无法编译并出现“表达式树可能不包含元组文字”错误。不幸的是,当将元组添加到语言中时,表达式树 API 并未扩展对元组的支持。
跟踪(并投票)此问题的更新:https://github.com/dotnet/roslyn/issues/12897
为了解决这个问题,你可以先将其转换为匿名类型,然后将值转换为元组:
// Will work
public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
return ctx.Persons
.Where(person => person.Id == id)
.Select(person => new { person.Name, person.Surname })
.ToList()
.Select(person => (person.Name, person.Surname))
.First();
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用 ValueTuple.Create:
// Will work
public static (string name, string surname) GetPersonName(this PersonContext ctx, int id)
{
return ctx.Persons
.Where(person => person.Id == id)
.Select(person => ValueTuple.Create(person.Name, person.Surname))
.First();
}
Run Code Online (Sandbox Code Playgroud)
参考:
有一项添加支持的提案:https ://github.com/dotnet/csharplang/issues/258
例子:
public static IQueryable<(string name, string surname)> GetPersonName(this PersonContext ctx, int id)
{
return ctx.Persons
.Where(person => person.Id == id)
.Select(person => ValueTuple.Create(person.Name, person.Surname));
}
// This won't work
ctx.GetPersonName(id).Select((name, surname) => { return name + surname; })
// But this will
ctx.GetPersonName(id).Select(t => { return t.name + t.surname; })
Run Code Online (Sandbox Code Playgroud)
参考:
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main() {
var me = (age: 21, favoriteFood: "Custard");
string json = JsonConvert.SerializeObject(me);
// Will output {"Item1":21,"Item2":"Custard"}
Console.WriteLine(json);
}
}
Run Code Online (Sandbox Code Playgroud)
元组字段名称仅在编译时可用,并在运行时完全擦除。
参考:
到今天为止,事情就这么简单。而不是使用 Tuple 关键字
public Tuple<int, int, int int> GetOrderRelatedIds()
Run Code Online (Sandbox Code Playgroud)
用这个。
public (int alpha, int beta, int candor) GetOrderRelatedIds()
Run Code Online (Sandbox Code Playgroud)
获取这样的值。
var a = GetOrderRelatedIds();
var c = a.alpha;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
96600 次 |
| 最近记录: |