一个小例子
TTest= class private f : T; public function ToString : string; end;
如果是一个对象,那么这应该工作
TTest.ToString; begin Result := f.ToString; end;
但是当说整数时会发生什么?这在.net中可以.当然.
我知道它不起作用,但我如何编写它来处理对象和简单类型?
Delphi不允许你在第二个例子中做你想做的事情有三个原因 - 在一个无约束类型参数类型的值上调用ToString方法(或者至少是我认为你试图显示的那个,因为TObject.ToString是一个实例方法,而不是一个类方法,所以T.ToString甚至不能用于TObject).
Delphi没有root类型系统,并且所有类型都很少有操作.这些操作 - 复制,分配,创建位置(字段,本地,参数,数组) - 是唯一可以保证在类型参数的所有可能值上可用的操作.
继1之后,为什么这些操作仅限于这些?为什么不允许泛型类中的操作,只在实例化时给出错误?好吧,第一部分原因是该设计最初旨在最大限度地兼容.NET和dccil,因此.NET泛型不允许的东西在Win32泛型设计中没有显着的可用性.
设计的第二个理由是,在实例化时只检查是有问题的.使用这种方法的最着名的参数多态实现是C++模板,它也以其神秘的错误消息而闻名,因为你试图将错误类型的迭代器传递给算法,并且得到关于未找到重载运算符的奇怪抱怨.多态性越深,问题就越严重.事实上,C++本身就是以C++ 0x Concepts的形式纠正这个错误.
希望您现在明白为什么不能保证通过约束无法保证可以使用的操作.但是,如Gamecat建议的那样,通过以方法引用或接口实现的形式提供操作,您可以相对容易地摆脱此限制.
将来,Delphi for Win32中的泛型可能会沿着类似的行扩展到C++ 0x Concepts或Haskell类型类,这样类型参数可能会受限于某些方法,函数和运算符可用.如果它沿着类型类行,那么类型推断也可以以这种方式进行.