基本上,我有一个应用程序,它将从INI文件中检索信息,并且该过程的一部分包括提取在INI中存储的名称 - 在另一个单元内的全局范围内声明的某些过程。
我使用以下内容来获取SQL方法:
MyIni.ReadString('SQL', SubStr + '_Insert, '');
SubStr是我想要的数据类型,例如“titles”,它以我想要的SQL过程类型为前缀,在本例中为“_Insert”,因此,我的请求可以看作:
MyIni.ReadString('SQL', 'titles_Insert', '');
然后将检索INI内显示的相应SQL 过程名称“InsertTitlesSql”:
[SQL]
titles_Insert=InsertTitlesSql
我有一个单元列出了我们使用的SQL过程。 像这样:
unit uSqlLibrary;
interface
function InsertTitlesSql: string;
implementation
function InsertTitlesSql: string;
begin
{
INSERT INTO TITLES (ENGLISH, AFRIKAANS, KEY)
VALUES (:english,
:afrikaans,
:key)
}
Result := ''
+'INSERT INTO TITLES (ENGLISH, AFRIKAANS, KEY) '
+'VALUES (:english, '
+' :afrikaans, '
+' :key) ';
end;
end.
我尝试了TGenericContainer没有任何成功,我也尝试了MethodAddress但我不知道如何告诉MethodAddress查看没有要引用的Object的其他单元(例如Form1.MethodAddress())我最好到目前为止的结果是:
type
TExec = procedure of object;
procedure TForm1.Button1Click(Sender: TObject);
var
M : TMethod ;
E : TExec ;
begin
M.Code := @Test; // Where "Test" is a procedure inside a secondary Unit.
E := TExec(M);
E;
end;
我要做的是按照我想要的名称获取SQL过程(函数 InsertTitlesSql :string;)并将其分配给行为方式相同的泛型方法。
我的团队负责人说他不想编辑uSqlLibrary;所以我不能那样做,而是想过用方法的名字来代替。欢迎任何其他建议。
希望这很清楚。对不起,如果不是(我使用的术语不太好xD)。如果可以的话,我会尽力详细说明你的问题。
答案 0 :(得分:3)
您无法使用RTTI枚举具有全局范围的过程。您可以枚举方法,因此可以将全局过程转换为静态类方法。
但是,您还声明您的团队负责人不希望您更改uSqlLibrary
。在我看来,这似乎有点短视。随意告诉他/她我是这么说的。
无论如何,如果您无法更改uSqlLibrary
,则无法使用RTTI。因此,您需要构建自己的查找表。使用通用字典:
uses
System.Generics.Collections;
var
ProcTable: TDictionary<string, TProc>;
以通常的方式实例化它。在程序启动时添加功能:
....
ProcTable.Add('InsertTitlesSql', InsertTitlesSql);
....
当你需要查看并打电话时,请执行以下操作:
var
Proc: TProc;
....
if not ProcTable.TryGetValue(ProcName, Proc) then
raise EProcNotFound.CreateFmt(...);
Proc();
默认情况下,用于密钥的默认相等比较器区分大小写。因此,您可以选择提供自定义相等比较器,用于比较没有区分大小写的键。