delphi - 在 Delphi 中强制转换泛型安全吗?

标签 delphi generics dictionary casting

我需要实现一个返回 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/

相关文章:

windows - 当最小化/恢复动画打开时,如何在删除任务栏按钮之前平滑地最小化窗口?

java - GWT.create(clazz) "generics"方法

java - 在 HashMap 中存储多个类型对象并检索它们

python - 根据值遍历决策树;迭代进入子词典?

delphi - 在 Delphi 中将 Length() 与多维动态数组一起使用

ios - 在 iOS 模拟器上部署 Delphi 应用程序时无法执行/usr/bin/xcrun simctl install...

c# - 无法从 List<Bar> 转换为 List<Foo>

java - 将请求参数转换为泛型类

haskell - Haskell monad 链接中的类型检查错误

mysql - 使用 DBNavigation 创建和修改 Delphi 数据库