分享
 
 
 

探讨.NET 2.0中Tuple的实现方法

王朝厨房·作者佚名  2007-01-04
窄屏简体版  字體: |||超大  

摘要:探讨.NET 2.0中Tuple的实现方法

我在介绍Visual Basic 9.0的时候,曾经多次提到Tuple这个概念,当时是作为匿名类型的实例出现的。现在我们单独来讨论一下这个概念。Tuple常常译为“组元”,在大部分支持Tuple的语言中,常常表示成员数目确定,每个成员类型也确定的结构。常常用于表示函数的多个返回值或者查询的结果等。Tuple应当是强类型的,即所有成员的类型在编译时确定。比如,假想语法下

Dim t = New Tuple(Of String, Integer, Double)

那么t将具有三个成员,该数目无法改变;同时三个成员的类型分别为String, Integer和Double,也无法改变。如你所见,Tuple可以看作不用事先声明的结构体,可以根据所使用的场合灵活地创建。那么VB9和C#3的匿名类型当然是Tuple很好的实现方案。但是这都是N年后的东西了,我们在.NET 2.0中能否实现Tuple?最关键的难点在于,我们要在希望使用的地方创建Tuple的结构,而不是事先声明,因此就必须有个灵活的机制来完成。

方法一:TypeList

我是某一天在公共汽车上想到这个办法,后来看到和Loki的TypeList有相似之处。当然.NET没有特化和记录类型的能力,所以无法实现TypeList。但我们把静态类型运算的思路移到运行时,就可以做Typed Variable List——那就是Tuple。

public abstract class TypeNode { internal TypeNode {} }

public sealed class Tail : TypeNode { }

public sealed class Tuple<T, TNode> : TypeNode where TNode : TypeNode, new()

{

public T Field = default(T);

public TNode Next = new TNode();

}

我充分利用了.NET泛型的约束特性来达成我的设计。TypeNode被设计为abstract,因此约束了new()的泛型参数TNode将无法取值TypeNode本身的类型。而其internal的构造函数又限制了用户继承于它。这个手法就将TNode的取值范围限定在Tail和Tuple两个类型上。这个用法是我认为约束用法中相当巧妙的一种。

这个类型的原理很简单,就是利用泛型,在创建TypeList的实例时自动生成相同结构的链表。比如我们要创建一个String, Integer, Double的Tuple,就是这样写:

Tuple<string, Tuple<int, Tuple<double, Tail>>> t;

如你所见,这种Tuple的类型参数第一个是某节点的类型,第二个要么是另一个Tuple,要么是Tail(表示终结列表)。这个对象创建出来以后就会自动生成一个“各个节点类型都不相同”的链表。

t = new Tuple<string, Tuple<int, Tuple<double, Tail>>>();

t.Field = " a string ";

t.Next.Field = 123;

t.Next.Next.Field = 13.56;

Tail没有Next字段,因此遇到Tail就代表Tuple终结了,这可以由编译器检查,因此没有越界的危险。而且这种Tuple可以达到无限长。不过这种方法也是有缺陷的,首先使用的语法方面非常不便,如果要用第7个字段,要写成myTuple.Next.Next.Next.Next.Next.Next.Field,稍不注意就会写错。无论VB还是C#都没有足够的抽象能力简化这一操作。第二个缺陷是建立Tuple时的一连串new操作开销很大,因为这里的new是通过反射进行的。所以受限于语言特性的缺乏,这种方法无法达到很完美的地步,不过这个思路也许在其他场合可以用上。

方法二:重载原型

模仿泛型委托的思路,我们可以用完全泛型化的一系列同名结构来模拟即时创建的Tuple:

struct Tuple<T0>

{

public T0 Field0;

}

struct Tuple<T0, T1>

{

public T0 Field0;

public T1 Field1;

}

struct Tuple<T0, T1, T2>

{

public T0 Field0;

public T1 Field1;

public T2 Field2;

}

......

struct Tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> {...}

这样就创建了一组Tuple结构。因为名称相同,在使用中不会察觉到存在10个类型,而是“要什么有什么”:

Tuple<string, int, double> t1;

Tuple<string, string> t2;

Tuple<int, int, int, int, float> t3;

......

这和我们一开始假想的语法一样!而且没有任何额外开销,相当完美。但是它的元素数目有限,一开始定义了几个就只能有几个,好在一般不需要太多,10个够用了。不过这样生成的Tuple有点死板,似乎没有什么可以智能化的地方。

我将在我的VBF中采用第二种Tuple方案,斟酌后还是觉得它比较实际。唯一改动的地方就是为每个Tuple结构增加了一个初始化所有成员的构造函数。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有