在“元组”中比“Item1”,“Item2”更好地命名
有没有办法使用Tuple类,但提供其中的项目的名称?
例如:
public Tuple<int, int, int int> GetOrderRelatedIds()
这将返回OrderGroupId,OrderTypeId,OrderSubTypeId和OrderRequirementId的ID。
这将是很好的,让我的方法的用户知道哪个是哪个。 (当你调用方法时,结果是result.Item1,result.Item2,result.Item3,result.Item4,不清楚哪一个是哪个。)
(我知道我可以创build一个类来容纳所有的Ids,但是这些Ids已经拥有自己的类,并且为这个方法的返回值创build一个类似乎是愚蠢的。)
在C#7.0(Visual Studio 2017)中有一个新的构build:
(string first, string middle, string last) LookupName(long id)
不,没有办法做到这一点没有定义自己的types。
这是你所问的一个过于复杂的版本:
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; } } }
为什么不上课呢?
使用.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.
值得一提的是在一个方法中的匿名types ,但是如果你想返回它,你需要创build一个类。
var MyStuff = new { PropertyName1 = 10, PropertyName2 = "string data", PropertyName3 = new ComplexType() };
如果你的项目的types是不同的,这是我为了让他们更直观的类。
这个类的用法:
var t = TypedTuple.Create("hello", 1, new MyClass()); var s = t.Get<string>(); var i = t.Get<int>(); var c = t.Get<MyClass>();
源代码:
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; } } }
不,你不能命名元组成员。
中间将使用ExpandoObject而不是Tuple。
我想我会创build一个类,但另一种select是输出参数。
public void GetOrderRelatedIds(out int OrderGroupId, out int OrderTypeId, out int OrderSubTypeId, out int OrderRequirementId)
由于你的Tuple只包含整数,你可以用Dictionary<string,int>
来表示它
var orderIds = new Dictionary<string, int> { {"OrderGroupId", 1}, {"OrderTypeId", 2}, {"OrderSubTypeId", 3}, {"OrderRequirementId", 4}. };
但我不build议这样做。
为什么每个人都过得如此艰苦。 元组是用于相当临时的数据处理。 一直工作与元组将使代码非常难以理解。 创build类的一切可能会最终膨胀你的项目。
这是关于平衡,但是…
你的问题似乎是你想要一个类的东西。 为了完整起见,下面这个类还包含构造函数。
这是适当的模式
- 自定义数据types
- 没有进一步的function。 Getters和setter也可以用代码扩展,获取/设置私有成员的名字模式为“_orderGroupId”,同时也执行function代码。
- 包含构造函数 如果所有的属性都是强制的,你也可以select只包含一个构造函数。
- 如果你想使用所有的构造函数,像这样冒泡是避免重复代码的正确模式。
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; } }
或者,如果你想要它真的很简单:你也可以使用types初始值设定项:
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; }
我将在总结中写入项目名称..所以通过hover在函数helloworld()上的文本将会说hello = Item1和world = Item2
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); }`
这非常烦人,我预计C#的未来版本将解决这个需求。 我发现最简单的工作是使用不同的数据结构types,或者为了您的理智和读取您的代码的其他人的理智,重命名“项目”。
Tuple<ApiResource, JSendResponseStatus> result = await SendApiRequest(); ApiResource apiResource = result.Item1; JSendResponseStatus jSendStatus = result.Item2;
你可以编写一个包含Tuple的类。
您需要重写Equals和GetHashCode函数
和==和!=运算符。
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)); } }
将返回:
真正
真正