在类声明中使用自己的类作为类型参数约束

时间:2016-01-05 11:41:48

标签: delphi generics forward-declaration delphi-xe8 type-constraints

我在Delphi XE8中有以下类的声明:

list_3 = []
converter = {'1.1':'1.7', '1.2':'1.8', '1.4':'1.9', '24':'25'}
for elem in list_1:
    if elem in list_2:
        list_3.append(converter[elem])
    else:
        list_3.append(elem)

会抛出以下编译器错误:

TestClass = class;
TestClass = class
  function test<T: TestClass>(supplier: TFunc<T>): T; // Compiler error
end;

当我在混合中添加另一个类并将其作为约束使用时,它可以正常工作:

E2086 Type 'TestClass' is not yet completely defined

我怀疑问题是前向类型声明还没有告诉Delphi足够的AnotherTestClass = class end; TestClass = class; TestClass = class function test<T: AnotherTestClass>(supplier: TFunc<T>): T; // No Error end; 类型。这可能更明显,因为以下尝试解决该问题会在不同的行上抛出相同的编译器错误:

TestClass

我做错了什么,如果没有,是否有办法解决这个问题?

1 个答案:

答案 0 :(得分:8)

你没有做错任何事。您正在尝试的应该是可能的,但在我看来,编译器是有缺陷的。如果不彻底改变设计,就没有可行的方法来解决这个问题。解决该问题的一种方法是在运行时强制执行约束。然而,在我看来,这将完全改变设计。

请注意,在.net中,你想要做的事情是完全可能的:

class MyClass
{
    private static T test<T>(Func<T> arg) where T : MyClass
    {
        return null;
    }
}

Delphi泛型功能基于.net泛型,我更倾向于怀疑您遇到的问题是Delphi开发人员的疏忽。

您应该提交错误报告/功能请求。

更新1

LU RD提出了一个更好的解决方法。使用类助手:

type
  TestClass = class
  end;

  TestClassHelper = class helper for TestClass
    function test<T: TestClass>(supplier: TFunc<T>): T;
  end;

这将允许您在编译时测试约束。但是,它确实强制您在函数外部定义不整齐的方法,并且它会阻止您将类助手用于任何其他目的。因此,您仍应在我的视图中提交错误报告/功能请求。

更新2

错误报告:RSP-13348