彭大虾文章 中,提出了一个有趣的预言--“C# designers can come up with a better syntax ”,
那么到底怎么个better法呢?
坐等结果没劲,我来斗胆猜一猜,若是猜不中,就当是搞笑一把为大家献丑。 ![]()
我猜测:
1,还是 traits的路子。没办法,模般特例化/traits 的概念确确实实摆在那里,绕不开的。
2,提供比C++ "better"的traits。
比如:
template <typename T> class TMD {...};
这里,C++语言本身提供的 特例化方案(我杜撰的词,不知道该怎么说),只能告诉编译器T是否是一个指针,
大致这样
template <typename T> class TMD<*T> {...}; //具体语法可能有出入,毕竟我不是写 xTL 的:)
(这里x = S,A,W ...呵呵)
如果你想告诉编译器更多的类型信息,比如"T是一个类,不过你可以用memcpy来复制他"之类,
对不起,请你自己写相应的traits。这可就苦了那些 xTL的大虾闷喽,随便哪一个STL容器背后都有无数traits呦。
还好,.net语言情况没有C++那么复杂,我大胆预测,
范型化.net语言提供两个"天生" 特例化方案,一个代表值类型另一个代表引用类型,就可以应付大部分xTL的要求。
比如
template <typename T> class TMD< 值类型 T> {...}
告诉编译器T是 int ,char 之类的东西,意味着BOX地不要,要比较就memcmp,要复制就memcpy...
而 template <typename T> class TMD< 引用类型 T> {...}
则诉编译器T是 object 之类的东西。
于是,彭大虾的那些令人望而生畏IComparer<T>之类,就可以休息了,
这 syntax 也就 better了,呵呵。
打印 | 张贴于 2004-04-09 16:20:00 | Tag:技术沾边
留言反馈
个人感觉VB.net的语法比C#的好理解,思路也更清楚点~~
"C++处理模板的 膨胀法 ,天生就适合实现特化。
然而,C#和java实现泛型所有的 擦拭法"
哎呦,真是见血封猴啊,长学问了。
不抛砖还真引不出玉,嘿嘿。
C++处理模板的 膨胀法 ,天生就适合实现特化。
然而,C#和java实现泛型所有的 擦拭法 (是的,我没说错,C#和java实现泛型的方法本质上是相同的,不同的只是java,把泛型参数替换为Object类,而C#替换成一个占位符罢了,当然由于CLR知道这种情况,所以C#的泛型效率应该比java略高)
to lostinet: 我好像没有发现加入了什么新的IL指令?连使用new约束时,产生T类型的实例也是用的反射。唯一不同的是,可以从一个类型占位符来获取一个type类型。
C++之所以用traits,是因为它的Template的语法游戏是:
能编译通过就是能用的,不通过就是不能用的.
traits就在用来这个语法游戏中限制更多的情况的.
(所以C++的Template类都是以原代码的形式提供被其他人使用的.)
dotnet的generics是不用traits这样的语法形式的.
具体原因是dotnet-generics类是允许预先编译好,然后以il的形式来储存它的定义.
所以dotnet使用实实在在的新的il指令来描述一个generics class里用到的类型的限制情况.
class Test2<T>where T : System.Object ?
BTW:VB的太冗长了,还是喜欢C那样符号化的写法。
Public Class Test(Of T As Class) '约束引用类型
Public Class Test2(Of T As Structure) '约束值类型
有些地方都不如VB.NET自然。
class Test<T>where T : struct //T只能是值类性
class Test2<T>where T : class //T只能是引用类型
可惜上面两个类无法取同一个名字,而且我怀疑值类型/引用类型约束到底有没有用,是不是只是在语法上限制不符合的类型,而不是从根本上区别值类型T和引用类型T.