RTTI:我可以通过名称获取类型吗?
给定一个包含类型名称的文本字符串,是否有某种方法可以获取适当的类型本身?
我想做这样的事情:
type
TSomeType<T> = class
// yadda yadda
end;
procedure DoSomething;
var
obj : TObject;
begin
o := TSomeType<GetTypeByName('integer')>.Create;
// do stuff with obj
end;
我在网上查看了一些 RTTI 解释,并浏览了 Delphi 单元,但没有看到我在寻找什么。这可能吗?
Given a text string containing a type name, is there some way to get the appropriate type itself?
I'm looking to do something like this:
type
TSomeType<T> = class
// yadda yadda
end;
procedure DoSomething;
var
obj : TObject;
begin
o := TSomeType<GetTypeByName('integer')>.Create;
// do stuff with obj
end;
I've looked at several RTTI explanations online and looked through the Delphi units and don't see what I'm looking for. Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,泛型完全是编译时的。
No, generics are entirely compiletime.
Delphi 2010 中的新 RTTI 单元有一种检索单元接口部分中声明的类型的方法。对于由
TRttiType
实例表示的任何给定类型,TRttiType.QualifiedName
属性返回一个名称,稍后可与TRttiContext.FindType
一起使用检索类型。限定名称是完整的单元名称(包括命名空间,如果存在),后跟“.”,然后是完整类型名称(包括外部类型,如果嵌套)。因此,您可以使用
context.FindType('System.Integer')
检索 Integer 类型的表示形式(以TRttiType
的形式)。但此机制不能用于检索在编译时未实例化的泛型类型的实例化;运行时实例化需要运行时代码生成。
The new RTTI unit in Delphi 2010 has a way of retrieving types declared in the interface section of units. For any given type, represented by a
TRttiType
instance, theTRttiType.QualifiedName
property returns a name that can be used withTRttiContext.FindType
later to retrieve the type. The qualified name is the full unit name (including namespaces, if they exist), followed by a '.', followed by the full type name (including outer types if it nested).So, you could retrieve a representation of the Integer type (in the form of a
TRttiType
) withcontext.FindType('System.Integer')
.But this mechanism can't be used to retrieve instantiations of generic types that weren't instantiated at compile time; instantiation at runtime requires runtime code generation.
您始终可以将类型注册到某种注册表中(由字符串列表或字典管理)并创建一个工厂函数以返回适当的对象。不幸的是,您必须提前知道您需要什么类型。类似于 Delphi 函数 RegisterClass 和 FindClass(在类单元中)。我的想法是直接将通用模板类型放入列表中。
可能用法的示例:
编辑:这是一个使用 Generics.Collections 中的 tDictionary 来处理注册表存储的特定简单实现...我将把它提取到有用的方法中作为一个简单的练习读者。
另一个编辑:昨晚我对此进行了一些思考,发现了另一种可以合并到这个概念中的技术。接口。这是一个快速的不执行任何操作的示例,但可以轻松扩展:
当然,您必须实现 QueryInterface、_AddRef 和 _Release 方法并扩展接口以执行更有用的操作。
You can always register your types into some sort of registry (managed by a string list or dictionary) and create a factory function to then return the appropriate object. Unfortunately you would have to know in advance what types you were going to need. Something similar to the Delphi functions RegisterClass and FindClass (in the classes unit). My thinking is to put the generic template type into the list directly.
An example of possible usage:
EDIT: Here is a specific simple implementation using a tDictionary from Generics.Collections to handle the registry storage...I'll leave extracting this into useful methods as a simple exercise for the reader.
Another EDIT: I was giving this some thought last night, and discovered another technique that you can merge into this concept. Interfaces. Here is a quick do nothing example, but can easily be extended:
of course you would have to implement the QueryInterface, _AddRef and _Release methods and extend the interface to do something more useful.
如果您忘记泛型和基本类型,“RegisterClass”函数会很有帮助。但它不适用于泛型或基本类型。
If you forget generics and basic types, the "RegisterClass" function would be helpful. But it doesn't work for generics or basic types.