在元组类中命名比“Item1”、“Item2”更好

时间:2021-11-06 06:57:18

Is there a way to use a Tuple class, but supply the names of the items in it?

是否有一种方法可以使用Tuple类,但要提供其中项目的名称?

For example:

例如:

public Tuple<int, int, int int> GetOrderRelatedIds()

That returns the ids for OrderGroupId, OrderTypeId, OrderSubTypeId and OrderRequirementId.

它返回OrderGroupId、OrderTypeId、OrderSubTypeId和OrderRequirementId的id。

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.)

让我的方法的用户知道哪个是哪个更好。调用方法时,结果就是结果。Item1,结果。第二条,结果。Item3 result.Item4。目前尚不清楚哪个是哪个。

(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.)

(我知道我可以创建一个类来保存所有这些id,但是这些id已经有了它们所在的类,为这个方法的返回值创建一个类似乎很愚蠢。)

12 个解决方案

#1


134  

In C# 7.0 (Visual Studio 2017) there is a new construction to do that:

在c# 7.0 (Visual Studio 2017)中,有一种新的结构可以做到这一点:

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

#2


46  

No, there is not a way to do this short of defining your own type.

不,除了定义自己的类型之外,没有其他方法可以做到这一点。

#3


29  

Here is an overly complicated version of what you are asking:

以下是一个过于复杂的问题:

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

}

Why not just make a class?

为什么不去上课呢?

#4


10  

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.

使用。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.

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.

值得一提的是方法中的匿名类型,但是如果您想要返回它,您需要创建一个类。

var MyStuff = new
    {
        PropertyName1 = 10,
        PropertyName2 = "string data",
        PropertyName3 = new ComplexType()
    };

#5


3  

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:

本课程的使用方法:

var t = TypedTuple.Create("hello", 1, new MyClass());
var s = t.Get<string>();
var i = t.Get<int>();
var c = t.Get<MyClass>();

Source code:

源代码:

public static class TypedTuple
{
    public static TypedTuple<T1> Create<T1>(T1 t1)
    {
        return new TypedTuple<T1>(t1);
    }

    public static TypedTuple<T1, T2> Create<T1, T2>(T1 t1, T2 t2)
    {
        return new TypedTuple<T1, T2>(t1, t2);
    }

    public static TypedTuple<T1, T2, T3> Create<T1, T2, T3>(T1 t1, T2 t2, T3 t3)
    {
        return new TypedTuple<T1, T2, T3>(t1, t2, t3);
    }

    public static TypedTuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 t1, T2 t2, T3 t3, T4 t4)
    {
        return new TypedTuple<T1, T2, T3, T4>(t1, t2, t3, t4);
    }

    public static TypedTuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
    {
        return new TypedTuple<T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5);
    }

    public static TypedTuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
    {
        return new TypedTuple<T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6);
    }

    public static TypedTuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
    {
        return new TypedTuple<T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7);
    }

    public static TypedTuple<T1, T2, T3, T4, T5, T6, T7, T8> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
    {
        return new TypedTuple<T1, T2, T3, T4, T5, T6, T7, T8>(t1, t2, t3, t4, t5, t6, t7, t8);
    }

}

public class TypedTuple<T>
{
    protected Dictionary<Type, object> items = new Dictionary<Type, object>();

    public TypedTuple(T item1)
    {
        Item1 = item1;
    }

    public TSource Get<TSource>()
    {
        object value;
        if (this.items.TryGetValue(typeof(TSource), out value))
        {
            return (TSource)value;
        }
        else
            return default(TSource);
    }

    private T item1;
    public T Item1 { get { return this.item1; } set { this.item1 = value; this.items[typeof(T)] = value; } }
}

public class TypedTuple<T1, T2> : TypedTuple<T1>
{
    public TypedTuple(T1 item1, T2 item2)
        : base(item1)
    {
        Item2 = item2;
    }

    private T2 item2;
    public T2 Item2 { get { return this.item2; } set { this.item2 = value; this.items[typeof(T2)] = value; } }
}

public class TypedTuple<T1, T2, T3> : TypedTuple<T1, T2>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3)
        : base(item1, item2)
    {
        Item3 = item3;
    }

    private T3 item3;
    public T3 Item3 { get { return this.item3; } set { this.item3 = value; this.items[typeof(T3)] = value; } }
}

public class TypedTuple<T1, T2, T3, T4> : TypedTuple<T1, T2, T3>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4)
        : base(item1, item2, item3)
    {
        Item4 = item4;
    }

    private T4 item4;
    public T4 Item4 { get { return this.item4; } set { this.item4 = value; this.items[typeof(T4)] = value; } }
}

public class TypedTuple<T1, T2, T3, T4, T5> : TypedTuple<T1, T2, T3, T4>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
        : base(item1, item2, item3, item4)
    {
        Item5 = item5;
    }

    private T5 item5;
    public T5 Item5 { get { return this.item5; } set { this.item5 = value; this.items[typeof(T5)] = value; } }
}

public class TypedTuple<T1, T2, T3, T4, T5, T6> : TypedTuple<T1, T2, T3, T4, T5>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
        : base(item1, item2, item3, item4, item5)
    {
        Item6 = item6;
    }

    private T6 item6;
    public T6 Item6 { get { return this.item6; } set { this.item6 = value; this.items[typeof(T6)] = value; } }
}

public class TypedTuple<T1, T2, T3, T4, T5, T6, T7> : TypedTuple<T1, T2, T3, T4, T5, T6>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
        : base(item1, item2, item3, item4, item5, item6)
    {
        Item7 = item7;
    }

    private T7 item7;
    public T7 Item7 { get { return this.item7; } set { this.item7 = value; this.items[typeof(T7)] = value; } }
}

public class TypedTuple<T1, T2, T3, T4, T5, T6, T7, T8> : TypedTuple<T1, T2, T3, T4, T5, T6, T7>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8)
        : base(item1, item2, item3, item4, item5, item6, item7)
    {
        Item8 = item8;
    }

    private T8 item8;
    public T8 Item8 { get { return this.item8; } set { this.item8 = value; this.items[typeof(T8)] = value; } }
}

#6


2  

No, you can't name the tuple members.

不,您不能命名元组成员。

The in-between would be to use ExpandoObject instead of Tuple.

中间是使用ExpandoObject而不是Tuple。

#7


1  

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

这是正确的模式

  • A custom data type
    • with no further functionality. Getters and setters can also be expanded with code, getting/setting private members with the name pattern of "_orderGroupId", while also executing functional code.
    • 没有进一步的功能。getter和setter也可以通过代码进行扩展,获取/设置名为“_orderGroupId”的私有成员,同时执行函数代码。
  • 没有其他功能的自定义数据类型。getter和setter也可以通过代码进行扩展,获取/设置名为“_orderGroupId”的私有成员,同时执行函数代码。
  • Including constructors. You can also choose to include just one constructor if all properties are mandatory.
  • 包括构造函数。如果所有属性都是强制性的,您还可以选择只包含一个构造函数。
  • If you want to use all constructors, bubbling like this is the proper pattern to avoid duplicate code.
  • 如果您想使用所有的构造函数,像这样冒泡是避免重复代码的正确模式。

public class OrderRelatedIds
{
    public int OrderGroupId { get; set; }
    public int OrderTypeId { get; set; }
    public int OrderSubTypeId { get; set; }
    public int OrderRequirementId { get; set; }

    public OrderRelatedIds()
    {
    }
    public OrderRelatedIds(int orderGroupId)
        : this()
    {
        OrderGroupId = orderGroupId;
    }
    public OrderRelatedIds(int orderGroupId, int orderTypeId)
        : this(orderGroupId)
    {
        OrderTypeId = orderTypeId;
    }
    public OrderRelatedIds(int orderGroupId, int orderTypeId, int orderSubTypeId)
        : this(orderGroupId, orderTypeId)
    {
        OrderSubTypeId = orderSubTypeId;
    }
    public OrderRelatedIds(int orderGroupId, int orderTypeId, int orderSubTypeId, int orderRequirementId)
        : this(orderGroupId, orderTypeId, orderSubTypeId)
    {
        OrderRequirementId = orderRequirementId;
    }
}

Or, if you want it really simple: You can also use type initializers:

或者,如果您想要非常简单:您还可以使用类型初始化器:

OrderRelatedIds orders = new OrderRelatedIds
{
    OrderGroupId = 1,
    OrderTypeId = 2,
    OrderSubTypeId = 3,
    OrderRequirementId = 4
};

public class OrderRelatedIds
{
    public int OrderGroupId;
    public int OrderTypeId;
    public int OrderSubTypeId;
    public int OrderRequirementId;
}

#8


0  

I think I would create a class but another alternative is output parameters.

我想我应该创建一个类,但是另一个选择是输出参数。

public void GetOrderRelatedIds(out int OrderGroupId, out int OrderTypeId, out int OrderSubTypeId, out int OrderRequirementId)

Since your Tuple only contains integers you could represent it with a Dictionary<string,int>

由于你的元组只包含整数,你可以用字典 来表示它 ,int>

var orderIds = new Dictionary<string, int> {
    {"OrderGroupId", 1},
    {"OrderTypeId", 2},
    {"OrderSubTypeId", 3},
    {"OrderRequirementId", 4}.
};

but I don't recommend that either.

但我也不建议这样做。

#9


0  

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

我会把项目名称写在summay里。因此,通过在函数helloworld()上悬停,文本将会显示hello = Item1和world = Item2

` helloworld("Hi1,Hi2");

“helloworld(“Hi1,Hi2”);

    /// <summary>
    /// Return hello = Item1 and world Item2
    /// </summary>
    /// <param name="input">string to split</param>
    /// <returns></returns>
    private static Tuple<bool, bool> helloworld(string input)
    {
        bool hello = false;
        bool world = false;
        foreach (var hw in input.Split(','))
        {
            switch (hw)
            {
                case "Hi1":
                    hello= true;
                    break;
                case "Hi2":
                    world= true;
                    break;
            }

        }

        return new Tuple<bool, bool>(hello, world);
    }`

#10


0  

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.

这很烦人,我希望c#的未来版本能够解决这个问题。我发现最简单的工作要么是使用不同的数据结构类型,要么重命名“项”,以便您保持头脑清醒,让阅读您代码的其他人保持头脑清醒。

        Tuple<ApiResource, JSendResponseStatus> result = await SendApiRequest();
        ApiResource apiResource = result.Item1;
        JSendResponseStatus jSendStatus = result.Item2;

#11


0  

Reproducing my answer from this post as it is a better fit here.

从这篇文章中复制我的答案,因为它更适合这里。

Starting C# v7.0 now it is possible to name the tuple properties which earlier used to default to names like Item1, Item2 and so on.

从c# v7.0开始,现在可以将tuple属性命名为Item1、Item2等名称。

Naming the properties of Tuple Literals:

命名元组文字的属性:

var myDetails = (MyName: "RBT_Yoga", MyAge: 22, MyFavoriteFood: "Dosa");
Console.WriteLine($"Name - {myDetails.MyName}, Age - {myDetails.MyAge}, Passion - {myDetails.MyFavoriteFood}");

The output on console:

在控制台的输出:

Name - RBT_Yoga, Age - 22, Passion - Dosa

名字- RBT_Yoga,年龄- 22岁,激情- Dosa

Returning Tuple (having named properties) from a method:

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

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

The output on console:

在控制台的输出:

Employee Details: Rasik, Bihari, Rasik-PC, 1000

员工信息:Rasik, Bihari, Rasik- pc, 1000

Creating a list of Tuples having named properties

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

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

Output on console:

在控制台输出:

1 - cow 5 - chickens 1 - airplane

1 -牛5 -鸡1 -飞机

I hope I've covered everything. In case, there is anything which I've missed then please give me a feedback in comments.

我希望我把一切都讲完了。如果我漏掉了什么,请在评论中给我一个反馈。

Note: My code snippets are using string interpolation feature of C# v7 as detailed here.

注意:我的代码片段使用c# v7的字符串插值特性。

#12


-1  

You Can write a class that contains the Tuple.

您可以编写一个包含Tuple的类。

You need to override the Equals and GetHashCode functions

您需要重写Equals和GetHashCode函数。

and the == and != operators.

和=和!=运算符。

class Program
{
    public class MyTuple
    {
        private Tuple<int, int> t;

        public MyTuple(int a, int b)
        {
            t = new Tuple<int, int>(a, b);
        }

        public int A
        {
            get
            {
                return t.Item1;
            }
        }

        public int B
        {
            get
            {
                return t.Item2;
            }
        }

        public override bool Equals(object obj)
        {
            return t.Equals(((MyTuple)obj).t);
        }

        public override int GetHashCode()
        {
            return t.GetHashCode();
        }

        public static bool operator ==(MyTuple m1, MyTuple m2)
        {
            return m1.Equals(m2);
        }

        public static bool operator !=(MyTuple m1, MyTuple m2)
        {
            return !m1.Equals(m2);
        }
    }

    static void Main(string[] args)
    {
        var v1 = new MyTuple(1, 2);
        var v2 = new MyTuple(1, 2);

        Console.WriteLine(v1 == v2);

        Dictionary<MyTuple, int> d = new Dictionary<MyTuple, int>();
        d.Add(v1, 1);

        Console.WriteLine(d.ContainsKey(v2));
    }
}

will return:

将返回:

True

真正的

True

真正的

#1


134  

In C# 7.0 (Visual Studio 2017) there is a new construction to do that:

在c# 7.0 (Visual Studio 2017)中,有一种新的结构可以做到这一点:

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

#2


46  

No, there is not a way to do this short of defining your own type.

不,除了定义自己的类型之外,没有其他方法可以做到这一点。

#3


29  

Here is an overly complicated version of what you are asking:

以下是一个过于复杂的问题:

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

}

Why not just make a class?

为什么不去上课呢?

#4


10  

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.

使用。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.

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.

值得一提的是方法中的匿名类型,但是如果您想要返回它,您需要创建一个类。

var MyStuff = new
    {
        PropertyName1 = 10,
        PropertyName2 = "string data",
        PropertyName3 = new ComplexType()
    };

#5


3  

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:

本课程的使用方法:

var t = TypedTuple.Create("hello", 1, new MyClass());
var s = t.Get<string>();
var i = t.Get<int>();
var c = t.Get<MyClass>();

Source code:

源代码:

public static class TypedTuple
{
    public static TypedTuple<T1> Create<T1>(T1 t1)
    {
        return new TypedTuple<T1>(t1);
    }

    public static TypedTuple<T1, T2> Create<T1, T2>(T1 t1, T2 t2)
    {
        return new TypedTuple<T1, T2>(t1, t2);
    }

    public static TypedTuple<T1, T2, T3> Create<T1, T2, T3>(T1 t1, T2 t2, T3 t3)
    {
        return new TypedTuple<T1, T2, T3>(t1, t2, t3);
    }

    public static TypedTuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 t1, T2 t2, T3 t3, T4 t4)
    {
        return new TypedTuple<T1, T2, T3, T4>(t1, t2, t3, t4);
    }

    public static TypedTuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
    {
        return new TypedTuple<T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5);
    }

    public static TypedTuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
    {
        return new TypedTuple<T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6);
    }

    public static TypedTuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
    {
        return new TypedTuple<T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7);
    }

    public static TypedTuple<T1, T2, T3, T4, T5, T6, T7, T8> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
    {
        return new TypedTuple<T1, T2, T3, T4, T5, T6, T7, T8>(t1, t2, t3, t4, t5, t6, t7, t8);
    }

}

public class TypedTuple<T>
{
    protected Dictionary<Type, object> items = new Dictionary<Type, object>();

    public TypedTuple(T item1)
    {
        Item1 = item1;
    }

    public TSource Get<TSource>()
    {
        object value;
        if (this.items.TryGetValue(typeof(TSource), out value))
        {
            return (TSource)value;
        }
        else
            return default(TSource);
    }

    private T item1;
    public T Item1 { get { return this.item1; } set { this.item1 = value; this.items[typeof(T)] = value; } }
}

public class TypedTuple<T1, T2> : TypedTuple<T1>
{
    public TypedTuple(T1 item1, T2 item2)
        : base(item1)
    {
        Item2 = item2;
    }

    private T2 item2;
    public T2 Item2 { get { return this.item2; } set { this.item2 = value; this.items[typeof(T2)] = value; } }
}

public class TypedTuple<T1, T2, T3> : TypedTuple<T1, T2>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3)
        : base(item1, item2)
    {
        Item3 = item3;
    }

    private T3 item3;
    public T3 Item3 { get { return this.item3; } set { this.item3 = value; this.items[typeof(T3)] = value; } }
}

public class TypedTuple<T1, T2, T3, T4> : TypedTuple<T1, T2, T3>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4)
        : base(item1, item2, item3)
    {
        Item4 = item4;
    }

    private T4 item4;
    public T4 Item4 { get { return this.item4; } set { this.item4 = value; this.items[typeof(T4)] = value; } }
}

public class TypedTuple<T1, T2, T3, T4, T5> : TypedTuple<T1, T2, T3, T4>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
        : base(item1, item2, item3, item4)
    {
        Item5 = item5;
    }

    private T5 item5;
    public T5 Item5 { get { return this.item5; } set { this.item5 = value; this.items[typeof(T5)] = value; } }
}

public class TypedTuple<T1, T2, T3, T4, T5, T6> : TypedTuple<T1, T2, T3, T4, T5>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
        : base(item1, item2, item3, item4, item5)
    {
        Item6 = item6;
    }

    private T6 item6;
    public T6 Item6 { get { return this.item6; } set { this.item6 = value; this.items[typeof(T6)] = value; } }
}

public class TypedTuple<T1, T2, T3, T4, T5, T6, T7> : TypedTuple<T1, T2, T3, T4, T5, T6>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
        : base(item1, item2, item3, item4, item5, item6)
    {
        Item7 = item7;
    }

    private T7 item7;
    public T7 Item7 { get { return this.item7; } set { this.item7 = value; this.items[typeof(T7)] = value; } }
}

public class TypedTuple<T1, T2, T3, T4, T5, T6, T7, T8> : TypedTuple<T1, T2, T3, T4, T5, T6, T7>
{
    public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8)
        : base(item1, item2, item3, item4, item5, item6, item7)
    {
        Item8 = item8;
    }

    private T8 item8;
    public T8 Item8 { get { return this.item8; } set { this.item8 = value; this.items[typeof(T8)] = value; } }
}

#6


2  

No, you can't name the tuple members.

不,您不能命名元组成员。

The in-between would be to use ExpandoObject instead of Tuple.

中间是使用ExpandoObject而不是Tuple。

#7


1  

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

这是正确的模式

  • A custom data type
    • with no further functionality. Getters and setters can also be expanded with code, getting/setting private members with the name pattern of "_orderGroupId", while also executing functional code.
    • 没有进一步的功能。getter和setter也可以通过代码进行扩展,获取/设置名为“_orderGroupId”的私有成员,同时执行函数代码。
  • 没有其他功能的自定义数据类型。getter和setter也可以通过代码进行扩展,获取/设置名为“_orderGroupId”的私有成员,同时执行函数代码。
  • Including constructors. You can also choose to include just one constructor if all properties are mandatory.
  • 包括构造函数。如果所有属性都是强制性的,您还可以选择只包含一个构造函数。
  • If you want to use all constructors, bubbling like this is the proper pattern to avoid duplicate code.
  • 如果您想使用所有的构造函数,像这样冒泡是避免重复代码的正确模式。

public class OrderRelatedIds
{
    public int OrderGroupId { get; set; }
    public int OrderTypeId { get; set; }
    public int OrderSubTypeId { get; set; }
    public int OrderRequirementId { get; set; }

    public OrderRelatedIds()
    {
    }
    public OrderRelatedIds(int orderGroupId)
        : this()
    {
        OrderGroupId = orderGroupId;
    }
    public OrderRelatedIds(int orderGroupId, int orderTypeId)
        : this(orderGroupId)
    {
        OrderTypeId = orderTypeId;
    }
    public OrderRelatedIds(int orderGroupId, int orderTypeId, int orderSubTypeId)
        : this(orderGroupId, orderTypeId)
    {
        OrderSubTypeId = orderSubTypeId;
    }
    public OrderRelatedIds(int orderGroupId, int orderTypeId, int orderSubTypeId, int orderRequirementId)
        : this(orderGroupId, orderTypeId, orderSubTypeId)
    {
        OrderRequirementId = orderRequirementId;
    }
}

Or, if you want it really simple: You can also use type initializers:

或者,如果您想要非常简单:您还可以使用类型初始化器:

OrderRelatedIds orders = new OrderRelatedIds
{
    OrderGroupId = 1,
    OrderTypeId = 2,
    OrderSubTypeId = 3,
    OrderRequirementId = 4
};

public class OrderRelatedIds
{
    public int OrderGroupId;
    public int OrderTypeId;
    public int OrderSubTypeId;
    public int OrderRequirementId;
}

#8


0  

I think I would create a class but another alternative is output parameters.

我想我应该创建一个类,但是另一个选择是输出参数。

public void GetOrderRelatedIds(out int OrderGroupId, out int OrderTypeId, out int OrderSubTypeId, out int OrderRequirementId)

Since your Tuple only contains integers you could represent it with a Dictionary<string,int>

由于你的元组只包含整数,你可以用字典 来表示它 ,int>

var orderIds = new Dictionary<string, int> {
    {"OrderGroupId", 1},
    {"OrderTypeId", 2},
    {"OrderSubTypeId", 3},
    {"OrderRequirementId", 4}.
};

but I don't recommend that either.

但我也不建议这样做。

#9


0  

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

我会把项目名称写在summay里。因此,通过在函数helloworld()上悬停,文本将会显示hello = Item1和world = Item2

` helloworld("Hi1,Hi2");

“helloworld(“Hi1,Hi2”);

    /// <summary>
    /// Return hello = Item1 and world Item2
    /// </summary>
    /// <param name="input">string to split</param>
    /// <returns></returns>
    private static Tuple<bool, bool> helloworld(string input)
    {
        bool hello = false;
        bool world = false;
        foreach (var hw in input.Split(','))
        {
            switch (hw)
            {
                case "Hi1":
                    hello= true;
                    break;
                case "Hi2":
                    world= true;
                    break;
            }

        }

        return new Tuple<bool, bool>(hello, world);
    }`

#10


0  

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.

这很烦人,我希望c#的未来版本能够解决这个问题。我发现最简单的工作要么是使用不同的数据结构类型,要么重命名“项”,以便您保持头脑清醒,让阅读您代码的其他人保持头脑清醒。

        Tuple<ApiResource, JSendResponseStatus> result = await SendApiRequest();
        ApiResource apiResource = result.Item1;
        JSendResponseStatus jSendStatus = result.Item2;

#11


0  

Reproducing my answer from this post as it is a better fit here.

从这篇文章中复制我的答案,因为它更适合这里。

Starting C# v7.0 now it is possible to name the tuple properties which earlier used to default to names like Item1, Item2 and so on.

从c# v7.0开始,现在可以将tuple属性命名为Item1、Item2等名称。

Naming the properties of Tuple Literals:

命名元组文字的属性:

var myDetails = (MyName: "RBT_Yoga", MyAge: 22, MyFavoriteFood: "Dosa");
Console.WriteLine($"Name - {myDetails.MyName}, Age - {myDetails.MyAge}, Passion - {myDetails.MyFavoriteFood}");

The output on console:

在控制台的输出:

Name - RBT_Yoga, Age - 22, Passion - Dosa

名字- RBT_Yoga,年龄- 22岁,激情- Dosa

Returning Tuple (having named properties) from a method:

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

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

The output on console:

在控制台的输出:

Employee Details: Rasik, Bihari, Rasik-PC, 1000

员工信息:Rasik, Bihari, Rasik- pc, 1000

Creating a list of Tuples having named properties

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

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

Output on console:

在控制台输出:

1 - cow 5 - chickens 1 - airplane

1 -牛5 -鸡1 -飞机

I hope I've covered everything. In case, there is anything which I've missed then please give me a feedback in comments.

我希望我把一切都讲完了。如果我漏掉了什么,请在评论中给我一个反馈。

Note: My code snippets are using string interpolation feature of C# v7 as detailed here.

注意:我的代码片段使用c# v7的字符串插值特性。

#12


-1  

You Can write a class that contains the Tuple.

您可以编写一个包含Tuple的类。

You need to override the Equals and GetHashCode functions

您需要重写Equals和GetHashCode函数。

and the == and != operators.

和=和!=运算符。

class Program
{
    public class MyTuple
    {
        private Tuple<int, int> t;

        public MyTuple(int a, int b)
        {
            t = new Tuple<int, int>(a, b);
        }

        public int A
        {
            get
            {
                return t.Item1;
            }
        }

        public int B
        {
            get
            {
                return t.Item2;
            }
        }

        public override bool Equals(object obj)
        {
            return t.Equals(((MyTuple)obj).t);
        }

        public override int GetHashCode()
        {
            return t.GetHashCode();
        }

        public static bool operator ==(MyTuple m1, MyTuple m2)
        {
            return m1.Equals(m2);
        }

        public static bool operator !=(MyTuple m1, MyTuple m2)
        {
            return !m1.Equals(m2);
        }
    }

    static void Main(string[] args)
    {
        var v1 = new MyTuple(1, 2);
        var v2 = new MyTuple(1, 2);

        Console.WriteLine(v1 == v2);

        Dictionary<MyTuple, int> d = new Dictionary<MyTuple, int>();
        d.Add(v1, 1);

        Console.WriteLine(d.ContainsKey(v2));
    }
}

will return:

将返回:

True

真正的

True

真正的