我需要实现一个返回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"));
}
答案 0 :(得分:3)
不,没有“所有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(指针),这似乎工作得很好,但当你在代码中找回它时,它知道第二个参数应该是什么,你就遇到了一个大问题。
通过在接收函数上设置约束,有一些方法可以让Generics按照您的预期工作而不会破坏类型安全,但是Delphi目前没有实现它。 Delphi Prism确实如此,我一直试图让Delphi团队在下一个版本中实现它,但我们必须看到...
答案 1 :(得分:0)
调用GetMap时,您已经知道结果将是TDictionary。为什么不创建T和U的Generic函数GetMap,它返回T和U的TDictionary?
像这样:
function GetMap<T, U>: TDictionary<T, U>;
然后你可以不进行强制转换:
var
MyMap: TMyMapType;
begin
MyMap := GetMap<string, integer>();