我需要实现一个返回 TDictionary 的函数,而不指定确切的类型。返回的值可能是 TDictionary<string,Integer>
, TDictionary<string,string>
或TDictionary<string,Boolean>
我可以用 TDictionary 作为结果参数声明该函数吗:
function GetMap: TDictionary;
然后转换返回值:
type
TMyMapType: TDictionary<string,Integer>;
var
MyMap: TMyMapType:
begin
...
MyMap := GetMap as TMyMapType;
...
end;
编辑:发现似乎无法声明与我的三个字典类型类型兼容的“通用”结果参数类型。
看起来我需要类似的东西
type
TMyMapType: TDictionary<string, ?>;
这在 Object Pascal 语言中(还?)是不可能的。在 Java 中,它会是这样的:
static Map<String, Integer>getIntegerMap() {
Map<String, Integer> result = new TreeMap<String, Integer>() {};
result.put("foo", Integer.valueOf(42));
return result;
}
static Map<String, ?> getMap() {
return getIntegerMap();
}
public static void main(String[] args) {
System.out.println(getMap().get("foo"));
}
最佳答案
不,不存在“所有 TDictionary 版本都源自的基本 TDictionary 类”。参数类型是类类型的一部分。 TDictionary<T, U>
的父类是 TEnumerable<TPair<T, U>>
,其父类是 TObject
.
这有点烦人,但有必要保持类型安全。假设您有一个 TDictionary<string, TMyObject>
,然后您将其传递给一个需要 TDictionary<string, TObject>
的函数。 。您可能希望这能起作用,因为您可以将 TMyObject 传递给 TObject 参数。但事实并非如此,而且这是有充分理由的。
编译器无法在编译时检查接收函数内的实际类型,因此没有什么可以阻止例程获取字典并调用 .Add(Self.Name, Self)
,其中 Self 是 TForm(或其他任何东西)而不是 TMyObject。由于所有对象引用的大小都是 sizeof(pointer) ,因此这似乎工作得很好,但是当您将其返回到知道第二个参数应该是什么的代码中时,您就会遇到一个大问题。 p>
有一些方法可以通过对接收函数施加约束来使泛型按您的预期工作,而不破坏类型安全性,但 Delphi 目前尚未实现它。 Delphi Prism 确实如此,我一直在努力让 Delphi 团队在下一个版本中实现它,但我们必须看看...
关于delphi - 在 Delphi 中强制转换泛型安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1858917/