鸟语天空
System.Tuple类型
post by:追风剑情 2021-3-15 13:53

[微软] 元组类型
[微软] System.Tuple
[微软] System.ValueTuple

在System命名空间,Microsoft定义了几个泛型Tuple类型,它们全部从Object派生,区别只在于元数(泛型参数的个数)。
示例——Tuple
// 这是最简单的:
[Serializable]
public class Tuple<T1> {
	private T1 m_Item1;
	public Tuple(T1 item1) { m_Item1 = item1; }
	public T1 Item1 { get { return m_Item1; } }
}

// 这是最复杂的
[Serializable]
public class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> {
	private T1 m_Item1;
	private T2 m_Item2;
	private T3 m_Item3;
	private T4 m_Item4;
	private T5 m_Item5;
	private T6 m_Item6;
	private T7 m_Item7;
	private TRest m_Rest;
	
	public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5,
		T6 item6, T7 item7, TRest rest) {
		m_Item1 = item1;
		m_Item2 = item2;
		m_Item3 = item3;
		m_Item4 = item4;
		m_Item5 = item5;
		m_Item6 = item6;
		m_Item7 = item7;
		m_Rest = rest;
	}
	
	public T1 Item1 { get { return m_Item1; } }
	public T2 Item2 { get { return m_Item2; } }
	public T3 Item3 { get { return m_Item3; } }
	public T4 Item4 { get { return m_Item4; } }
	public T5 Item5 { get { return m_Item5; } }
	public T6 Item6 { get { return m_Item6; } }
	public T7 Item7 { get { return m_Item7; } }
	public TRest Rest { get { return m_Rest; } }
}

和匿名类型相似,Tuple创建好之后就不可变了(所有属性都只读)。虽然这里没有显示,但Tuple类还提供了CompareTo,Equals,GetHashCodeToString方法以及Size属性。此外,所有Tuple类型都实现了IStructuralEquatable,IStructuralComparableIComparable接口,所以可以比较两个Tuple对象,对它们的字段进行比对。

示例——Tuple
// 用Item1返回最小值,用Item2返回最大值
private static Tuple<Int32, Int32> MinMax(Int32 a, Int32 b) {
	return new Tuple<Int32, Int32>(Math.Min(a,b), Math.Max(a,b));
	//也可以用Create方法创建Tuple
	//return Tuple.Create(Math.Min(a,b), Math.Max(a,b));
}

// 下面展示如何调用方法,以及如何使用返回的Tuple
private static void TupleTypes() {
	var minmax = MinMax(6, 2);
	Console.WriteLine("Min={0}, Max={1}", minmax.Item1, minmax.Item2);
}

示例——Tuple
// 要创建多于8个元素的Tuple,可为Rest参数传递另一个Tuple
var t = Tuple.Create(0,1,2,3,4,5,6, Tuple.Create(7,8));
Console.WriteLine("{0},{1},{2},{3},{4},{5},{6},{7},{8}",
	t.Item1, t.Item2, t.Item3, t.Item4, t.Item5, t.Item6,
	t.Item7, t.Rest.Item1.Item1, t.Rest.Item1.Item2);

除了匿名类型和Tuple类型,还可以研究一下System.Dynamic.ExpandoObject类(在System.Core.dll程序集中定义)。这个类和C#的dynamic类型配合使用,就可用另一种方式将一系列属性(键/值对)组合到一起。虽然实现不了编译时的类型安全性,但语法看起来不错(虽然得不到“智能感知”支持),而且还可以在C#和Python这样的动态语言之间传递ExpandoObject对象。以下是使用了一个ExpandoObject的示例代码:

示例——ExpandoObject
dynamic e = new System.Dynamic.ExpandoObject();
e.x = 6;	//添加一个Int32  ‘x’属性,其值为6
e.y = "Jeff";	//添加一个String ‘y’属性,其值为"Jeff"
e.z = null;	//添加一个Object ‘z’属性,其值为null

//查看所有属性及其值
foreach (var v in (IDictionary<String, Object>)e)
	Console.WriteLine("Key={0}, V={1}", v.Key, v.Value);
	
//删除'x'属性及其值
var d = (IDictionary<String, Object>)e;
d.Remove("x");

评论:
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容