编辑,澄清这个问题,因为我简化太多,从而消除了我实际上正面临为什么我不能在方法体之外声明一个通用的匿名方法?
这个问题我有在长身体的实现委托。
因此,我不想在我使用它的函数中声明它。
type
TTaskDelegate<A, B> = reference to procedure(const Data: IData);
//-----------^^^^^^ note the type parameters here
//-But no type parameters here---------------------------^^^^^^
的委托声明一样,这样我可以将其存储在一个看起来像记录:
TMultiDelegate = record
strict private
fAA: TTaskDelegate<TOmniValue, TOmniValue>;
fAB: TTaskDelegate<TOmniValue, IOmniBlockingCollection>;
fBA: TTaskDelegate<IOmniBlockingCollection, TOmniValue>;
fBB: TTaskDelegate<IOmniBlockingCollection, IOmniBlockingCollection>;
fSimple: TSimpleTaskDelegate;
fOutputCount: Integer;
function GetDelegateType: TDelegateType;
public
constructor Init(AA: TTaskDelegate<TOmniValue, TOmniValue>; const OutputCount: integer = 1); overload;
constructor Init(AB: TTaskDelegate<TOmniValue, IOmniBlockingCollection>; const OutputCount: integer = 1); overload;
.....
类型参数也起到提醒的通用程序的实现者是什么输入和输出类型是。
因为类型参数在方法头的其余部分中没有重复,所以在声明函数时必须保留它们。
因此Stefan的答案不起作用。
只是声明它作为单位常量(或单位变量)不起作用。
由于其通用签名,将其声明为单位过程也不起作用。
下面的代码无法编译:
样品A
const
Test: integer = 0;
const
DoesNotCompile: TTaskDelegate<TOmniValue, TOmniValue> =
procedure(const Data: IData)
begin
//Do stuff
end;
E2026 Constant expression expected
//This variant will not compile either.
procedure DoStuff<TOmniValue, TOmniValue>(const Data: IData)
begin
//DoStuff
end;
当我把它包在它的工作的功能。
样品B
function ListSplitterDelegate: TTaskDelegate<TOmniValue, TOmniValue>;
begin
Result:=
procedure(const Data: IData)
begin
//Do stuff
end;
end;
感觉有点画蛇添足这种方式来做到这一点。
有没有办法避免必须将通用匿名函数包装在另一个函数中?
在单元的初始化部分直接分配它不是一个好主意,因为这会导致内存泄漏报告。如果你想这样做,你应该把它放到一个例程中,并在初始化部分调用它。 –
@StefanGlienke有很多原因,这不是一个好主意。我只是用它来证明需要在运行时创建匿名方法。另外,将它放入常规会使我们回到使用Johan的'ListSplitterDelegate'的(更好的)解决方案的复杂程度,所以根本没有理由使用上述方法。 –