如何命名元组属性

本文关键字:属性 元组 何命名 | 更新日期: 2023-09-27 18:37:11

How 和 "canbe" 有组织地从返回带有参数名称的元组类型的方法返回,举个例子

private static Tuple<string, string> methodTuple()
{
    return new {Name = "Nick", Age = "Twenty"}; /*exception because need to new Tuple<string, string>(){Item1 = "Nick", Item2 = "Twenty"}o*/
}

并调用methodTuple.Name不像methodTuple.Item1....N之类的参数

这可能吗?

UPD:我想创建带有命名参数的对象,而无需新的命名类型。

如何命名元组属性

在 C# 7.0 (Visual Studio 2017) 中,有一个新选项可以执行此操作:

(string first, string middle, string last) LookupName(long id)

从 C# v7.0 开始,现在可以为元组属性指定自定义名称。早些时候,它们曾经具有默认名称,如 Item1Item2 等。让我们看一下现在可能的几个变化:

  1. 命名元组文本的属性

    var personDetails = (Name: "Foo", Age: 22, FavoriteFood: "Bar");
    Console.WriteLine($"Name - {personDetails.Name}, Age - {personDetails.Age}, Favorite Food - {personDetails.FavoriteFood}");
    

    控制台上的输出:

    姓名 - Foo, 年龄 - 22, 最喜欢的食物 - 酒吧

  2. 从方法返回元组(具有命名属性):

    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 ("Foo", "Bar", "Foo-PC", 1000);
    }
    

    控制台上的输出:

    员工详细信息: Foo, 酒吧, Foo-PC, 1000

  3. 创建具有命名属性的元组列表:

    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}");
    

    控制台上的输出:

    1 - cow  
    5 - chickens  
    1 - airplane
    

注意:本文中的代码片段使用了 C# 的字符串插值功能,该功能在版本 6 中引入,详见此处。

您需要声明一个帮助程序类才能执行此操作。

public class MyResult
{
    public string Name { get; set; }
    public string Age { get; set; }
}

您尝试返回的是匿名类型。顾名思义,您不知道它的名称是什么,因此无法声明返回它的方法。

匿名类型(C# 编程指南)

不能声明字段、属性、事件或返回类型的方法具有匿名类型。同样,您不能声明方法、属性、构造函数或索引器的形式参数为具有匿名类型。传递匿名类型或集合包含匿名类型,作为方法的参数,您可以将参数声明为类型对象。但是,这样做会击败强类型化的目的。如果必须存储查询结果或传递查询结果在方法边界之外,请考虑使用普通命名结构或类,而不是匿名类型。

更新

C#7 引入了内置于语言中的元组支持,并带有命名元组

(string name, int age) methodTuple()
{
    (...)
}

阅读更多关于 learn.microsoft.com:https://learn.microsoft.com/en-us/dotnet/articles/csharp/csharp-7#tuples

这在Tuple 中是不可能的,不。 为此,需要创建自己的新命名类型。

现在你可以在 C# 中使用元组名称来做到这一点

对于 lambda 表达式:

private static (string Name, string Age) methodTuple() => ( "Nick", "Twenty" );

private static (string Name, string Age) methodTuple()
{
    return ( "Nick", "Twenty" );
}

不要对Tuple使用类类型。使用基元类型在 Tuple 中设置名称。

我通常会创建一个派生自 Tuple 的新类型,并映射显式属性以返回基类的 ItemX 属性。例如:

public class Person : Tuple<string, string>
{
    public Key(string name, string age) : base(name, age) { }
    public string Name => Item1;
    public string Age => Item2;
}

不幸的是,使用"元组"类型无法做到这一点,因为它被定义为"Item1...N"在 MSDN 中。 因此,此异常是有效的。

此方法可以通过 3 种方式进行编译:1.) 将返回类型更改为对象 - 这将创建一个"匿名"类型,然后您可以稍后使用它。 如果您想稍后访问"名称"或"年龄"属性而无需进行一些额外的工作,则它不是特别有用。2.) 将返回类型更改为动态 - 这将允许您访问"Name"和"Age"属性,但会使整个程序(只是此方法实际所在的 DLL)稍慢,因为使用动态需要抛出一些强类型。3.) 创建一个类并将其用作返回类型。

示例代码如下:

private static object ObjectTuple()
        {
            return new { Name = "Nick", Age = "Twenty" };
        }
        private static dynamic DynamicTuple()
        {
            return new { Name = "Nick", Age = "Twenty" };
        }
        private static Temp TempTuple()
        {
            return new Temp{ Name = "Nick", Age = "Twenty" };
        }
        class Temp
        {
            public string Name { get; set; }
            public string Age { get; set; }
        }

根据我的说法,当您想从单个方法返回或获取许多内容时,最好将其返回类型设为 CLASS,但如果您打算使用本身就是 Class 的元组,那么为了更好地命名这个新类应该继承元组。 例如下面提到。

 public CustomReturn ExecuteTask( int a, string b, bool c, object d )
        {
        // Calling constructor of CustomReturn Class to set and get values
          return new CustomReturn(a,b,c,d);
        }
        internal class CustomReturn 
        // for tuple inherit from Tuple<int,string,bool,object,double>
        { 
          //for tuple public int A{ get {this.Item1} private set;}
          public int A{get;private set;}
          public string B{get;private set;}
          public bool C{get;private set;}
          public object D{get;private set;}
          public CustomReturn (int a, string b, bool c, object d )
              // use this line for tuple ": base( obj, boolean )"
            {
              this.A = a;
              this.B = b;
              this.C = c;
              this.D = d;
            }
        }
    Main(args)
    {
      var result = ExecuteTask( 10, "s", true, "object" );
      // now if u have inherited Tuple for CustomReturn class then 
      // on doing result. you will get your custom name as A,B,C,D for //Item1,Item2,Item3,Item4 respectively also these Item1,Item2,Item3,Item4 will also be there.
    }