C# 如何命名元组属性?

C# 如何命名元组属性?,c#,tuples,C#,Tuples,如何组织和“可以”从返回参数名称的元组类型的方法返回, 例如 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*/ } private静态元

如何组织和“可以”从返回参数名称的元组类型的方法返回, 例如

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*/
}
private静态元组methodTuple()
{
返回新的{Name=“Nick”,Age=“town”};/*异常,因为需要新建Tuple(){Item1=“Nick”,Item2=“town”}o*/
}
并调用参数,如
methodTuple.Name
而不是
methodTuple.Item1….N

这可能吗


UPD:我想用命名参数创建对象,但不使用新的命名类型。

这在使用
元组时是不可能的,不可以。您需要创建自己的新命名类型来完成此操作。

您需要声明一个帮助器类来完成此操作

public class MyResult
{
    public string Name { get; set; }
    public string Age { get; set; }
}
您试图返回的是匿名类型。顾名思义,您不知道它的名称,因此无法声明返回它的方法

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

更新

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

(string name, int age) methodTuple()
{
    (...)
}
在docs.microsoft.com上阅读更多信息:

您可以尝试动态:

    private static dynamic methodTuple()
    {
        return new { Name = "Nick", Age = "Twenty" }; 
    }

。。。但是返回定义的类型或结构是最好的,正如前面所提到的。

不幸的是,这不可能使用“Tuple”类型,因为它在MSDN中定义为“Item1…N”。所以这个例外是有效的

此方法可以通过3种方式编译: 1.)将返回类型更改为object-这将创建一个“匿名”类型,您可以稍后使用它。如果您希望稍后访问“Name”或“Age”属性而无需进行一些额外的工作,那么它并不是特别有用。 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; }
        }

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

公共类人物:元组
{
公钥(字符串名称,字符串年龄):基(名称,年龄){}
公共字符串名称=>Item1;
公共字符串年龄=>Item2;
}
在C#7.0(Visual Studio 2017)中,有一个新的选项可以做到这一点:

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

据我所知,当您想要从一个方法返回或获取很多东西时,最好将其返回类型设置为CLASS,但如果您打算使用本身就是CLASS的Tuple,那么为了更好地命名这个新类,应该从Tuple继承。e、 g.如下所述

 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.
    }
public CustomReturn ExecuteTask(int a、string b、bool c、object d)
{
//调用CustomReturn类的构造函数来设置和获取值
返回新的CustomReturn(a、b、c、d);
}
内部类自定义返回
//对于tuple,从tuple继承
{ 
//对于元组公共int{get{this.Item1}私有集;}
public int A{get;private set;}
公共字符串B{get;private set;}
公共布尔C{get;私有集;}
公共对象D{get;私有集;}
公共CustomReturn(整数a、字符串b、布尔c、对象d)
//将此行用于元组“:base(obj,boolean)”
{
这个A=A;
这个.B=B;
这个.C=C;
这个。D=D;
}
}
主(args)
{
var result=ExecuteTask(10,“s”,true,“object”);
//现在,如果您继承了CustomReturn类的元组,那么
//在执行结果时,您将分别获得//Item1、Item2、Item3、Item4的自定义名称A、B、C、D。这些Item1、Item2、Item3、Item4也将出现。
}
现在启动C#v7.0,可以命名元组属性,以前使用元组属性默认为
Item1
Item2
等名称

命名元组文字的属性

var myDetails = (MyName: "RBT_Yoga", MyAge: 22, MyFavoriteFood: "Dosa");
Console.WriteLine($"Name - {myDetails.MyName}, Age - {myDetails.MyAge}, Passion - {myDetails.MyFavoriteFood}");
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);
}
控制台上的输出:

姓名-RBT_瑜伽,22岁,激情-多萨

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

var myDetails = (MyName: "RBT_Yoga", MyAge: 22, MyFavoriteFood: "Dosa");
Console.WriteLine($"Name - {myDetails.MyName}, Age - {myDetails.MyAge}, Passion - {myDetails.MyFavoriteFood}");
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);
}
控制台上的输出:

员工详细信息: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}");
var tupleList=新列表
{
(1,“奶牛”),
(五)"鸡",,
(1,“飞机”)
};
foreach(元组列表中的变量元组)
WriteLine($“{tuple.Index}-{tuple.Name}”);
控制台上的输出:

1-奶牛 五只鸡 1-飞机

我希望我已经涵盖了一切。如果我错过了什么,请在评论中给我反馈


注意:我的代码片段正在使用C#v6的字符串插值功能,详情如下。

注意,您在这里定义的类型是可变的,而不是不变的,并且没有覆盖其值语义的相等语义,这与
元组
或匿名类型不同。不,这是不可能的。你想要实现什么?可能是@HamletHakobyan的复制品它终于可以启动C#v7.0了。我在这个帖子中添加了一个详细的答案来提供细节,这样他就失去了所有的静态类型安全性,显然破坏了拥有更多语义上有意义的类型信息(以及一些)的全部目的。它使代码明显比属性名为
Item1
Item2
更糟糕。