元组介绍






2.93/5 (27投票s)
本文将介绍在 C#4.0 中使用 Tuple 的一些好处。
引言
C#4.0 引入了一个新特性,称为 Tuple(元组)。
定义
在数学和计算机科学中,元组是元素的有序列表。 在集合论中,(有序)n 元组是 n 个元素的序列(或有序列表),其中 n 是一个正整数。 还有一个 0 元组,一个空序列。(来自维基百科)
目的
有时我们需要从方法或函数返回多个值。
使用代码
让我们进行一个简单的实验,了解基本算术运算的概念。
让我们首先编写我们的 Calculate 函数
/// Calculate private void Calculate(out int add, out int sub,out int mul,out int div) { int num1 = 5; int num2 = 4; add = num1 + num2; sub = num1 - num2; mul = num1 * num2; div = num1 / num2; }
旧方法 (Dotnet 3.5 之前)
方法 1:使用 OUT 参数
调用函数如下:
输出如预期:
方法 2:使用 REF 参数
与第一个类似,但将 OUT 更改为 REF
方法 3:使用自定义数据类型
创建一个 CalculateEntity,如下所示:
并修改我们的 Calculate 函数如下:
/// Calculate private static CalculateEntity Calculate() { CalculateEntity objCalculateEntity = new CalculateEntity(); int num1 = 5; int num2 = 4; objCalculateEntity.Add = num1 + num2; objCalculateEntity.Sub = num1 - num2; objCalculateEntity.Mul = num1 * num2; objCalculateEntity.Div = num1 / num2; return objCalculateEntity; }
调用函数现在将是:
方法 4:新方法 (Dotnet 4.0) - 使用 Tuple
可以看出,使用 Tuple 我们可以以更好、更易读的方式从函数/方法返回多个值。
上面的示例表明元组只返回相同类型的数据类型。
现在让我们看看如何从元组返回不同的数据类型
让我们修改上面的 Calculate 函数,使最后一个参数为 double。
结果符合预期
Tuple 的重载方法
Tuple 有 8 个重载方法,其签名如下:
1-Tuple 或 Singleton (单例)
public static TupleCreate (T1 item1);
2-Tuple 或 Pair (对)
public static TupleCreate (T1 item1, T2 item2);
3-Tuple 或 Triple (三元组)
public static TupleCreate (T1 item1, T2 item2, T3 item3);
4-Tuple 或 Quadruple (四元组)
public static TupleCreate (T1 item1, T2 item2, T3 item3, T4 item4);
5-Tuple 或 Quintuple (五元组)
public static TupleCreate (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5);
6-Tuple 或 SexTuple (六元组)
public static TupleCreate (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6);
7-Tuple 或 SepTuple (七元组)
public static TupleCreate (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7);
8-Tuple 或 Octuple (八元组)
public static Tuple> Create (T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8);
仔细观察最后一个重载方法,即八元组,可以发现最后一个参数又是元组,这意味着它可以携带另外 8 个项目,并且该过程继续进行。
让我们看看如何使用最后一个重载方法。
在这里,我将构建一个简单的乘法表,它将使用最后一个重载方法。
乘法表函数如下:
我们已经突出显示了第 8 个参数以及如何使用它。
调用函数同样简单
int number = 5; var tuple = MultiplicationTable(number); string format = "Multiplcation Table of {0} is" + Environment.NewLine + "------------------------------" + Environment.NewLine + Environment.NewLine + "{0} * 1 = {1} " + Environment.NewLine + "{0} * 2 = {2} " + Environment.NewLine + "{0} * 3 = {3} " + Environment.NewLine + "{0} * 4 = {4} " + Environment.NewLine + "{0} * 5 = {5} " + Environment.NewLine + "{0} * 6 = {6} " + Environment.NewLine + "{0} * 7 = {7} " + Environment.NewLine + "{0} * 8 = {8} " + Environment.NewLine + "{0} * 9 = {9} " + Environment.NewLine + "{0} * 10 = {10} " + Environment.NewLine; string result = string.Format( format , number , tuple.Item1 , tuple.Item2 , tuple.Item3 , tuple.Item4 , tuple.Item5 , tuple.Item6 , tuple.Item7 , tuple.Rest.Item1 , tuple.Rest.Item2 , tuple.Rest.Item3 ); Console.WriteLine(result); Console.ReadKey(true);
输出如下:
可以看出,使用它非常简单。
但是,如果我们需要在运行时确定元组上的参数数量怎么办。
这有点棘手,但通过使用反射可以很容易地完成。 让我们来看看
虽然对反射的完整详细介绍不在本文的范围内,但我们将逐步了解代码的作用。
在这一行
Type t = typeof(CSharpDemo.Program);
我们正在获取类的类型,这里是 Program。
然后通过使用 InvokeMember,我们正在调用该方法,这里是 MultiplicationTable。 由于它接受一个参数,因此我们在最后一个参数中传递相同的参数。
InvokeMember 返回一个对象,并且在将该对象强制转换为字符串并进行字符串替换后,我们通过逗号 (,) 分割该对象。
然后,通过应用 新的 Enumerable.Zip 扩展方法,其通用签名是 Enumerable .Zip<TFirst,TSecond,TResult>,我们合并两个序列,以便获得所需的显示格式,最后通过使用 Foreach 扩展方法,我们显示所需的结果。
在 Tuple 上创建自定义扩展方法
元组缺少 ItemCount 或 ItemValues 等的亮点。 但我们可以通过使用 Tuple 上的扩展方法来创建它们。 让我们看看如何。
创建一个名为 TupleExtension.cs 的类并编写以下代码
using System; using System.Linq; using System.Reflection; namespace CSharpDemo { public static class TupleExtension { public static TupleGetLengthAndMemeberValues(this Tuple targetTuple, string methodName, object[] param) { //Obtain the type of the class Type t = typeof(CSharpDemo.Program); //Create an instance of the class object classInstance = Activator.CreateInstance(t); //Invoke the method object memberValues = t.InvokeMember(methodName, BindingFlags.InvokeMethod, null, classInstance, param); //Assign the needed value to the target tuple targetTuple = new Tuple (ItemCount(memberValues), memberValues); return targetTuple; } /// /// ItemCount /// Get the count of the number of items /// /// ///int public static int ItemCount(object o) { return o.ToString() .Replace("(", string.Empty) .Replace(")", string.Empty) .Split(',').Count(); } } }
要使用扩展方法,我们可以继续执行如下所述:
TupletestTuple = new Tuple (0,null); var resultantTuple = testTuple .GetLengthAndMemeberValues("MultiplicationTable" , new object[] { number }); Console.WriteLine("Number of TupleItems" + resultantTuple.Item1); Console.WriteLine("Items of Tuple" + resultantTuple.Item2);
输出如下:
结论
在这个简短的教程中,我们尝试解释使用元组的大部分方法,它的用处,以及如何增加元组克服其可能遇到的缺点的功能的扩展方法。 本文还简要概述了新的 Zip 扩展方法及其用法。 我已将示例代码以及本文一起附加。 随意使用并根据您的要求进行修改。
非常感谢您对该主题的评论,以便改进该主题。
感谢阅读本文。