2012-12-20 52 views
4

我遇到了仿制药的问题。我不知道如何将OnCallbackWrapper传递给CallbackWrapper程序。我收到以下例子“不兼容的类型”错误:为什么编译器会为我的泛型函数参数抱怨“不兼容的类型”?

unit uTest; 

interface 

uses 
    Generics.Defaults; 

type 
    TGenericCallback<T> = procedure(Fields: T); 

type 
    TSpecificFields = record 
    A: Integer; 
    B: Integer; 
    C: Integer; 
    end; 

const 
    SpecificFields: TSpecificFields = 
    (A: 5; B: 4; C: 3); 

procedure CallbackWrapper(GenericCallback: TGenericCallback<TSpecificFields>); 

implementation 

procedure CallbackWrapper(GenericCallback: TGenericCallback<TSpecificFields>); 
begin 
    GenericCallback(SpecificFields); 
end; 

procedure OnCallbackWrapper(const Fields: TSpecificFields); 
begin 
    Assert(Fields.A = 5); 
    Assert(Fields.B = 4); 
    Assert(Fields.C = 3); 
end; 

procedure Dummy; 
begin 
    CallbackWrapper(OnCallbackWrapper); //Incompatible types here 
end; 

end. 

我在做什么错?谢谢。由值

回答

7
procedure OnCallbackWrapper(Fields: TSpecificFields); 
begin 
    Assert(Fields.A = 5); 
    Assert(Fields.B = 4); 
    Assert(Fields.C = 3); 
end; 

或改变声明

TGenericCallback<T> = procedure(const Fields: T); 

一个过程传递参数是不分配与通过引用传递参数的过程兼容。 Reference

+1

如果它解释了为什么需要进行这些更改,我会投这个票。顺便说一句,我明白用英语写解释可能对你并不容易,但我更喜欢任何解释,不管英语多么糟糕,完全没有解释。并且:你练习的越多,得到的就越好:-) –

+0

除了我的英语问题 ,我觉得这是膨胀的明显的事情要详细解释。 这是一个相当默默无闻的人的个人问题。我会尽量适应,但它不适合我的个性。 – bummi

+1

我可以与此相关。如果可以的话,那会很好。请注意,我狡猾地期待着漫长的讨论。只是一些帮助人们理解你的答案的提示(这很有用)。例如,以这个答案为例,没有解释强迫人们寻找差异。你做的编辑确实有帮助!另外:不要害怕犯英文错误。很多人愿意并能够编辑你的答案,使英语更好。 –

8

您声明的类型通过值接收其参数。

TGenericCallback<T> = procedure(Fields: T); // no const 

传递函数标有const

procedure OnCallbackWrapper(const Fields: TSpecificFields); // const parameter 

因此,编译器会拒绝您尝试传递的参数不匹配。你需要让双方都相配。例如:

TGenericCallback<T> = procedure(const Fields: T); 
+0

你们很快:)我知道我忽略了一些东西。这两个答案都对大卫有帮助,所以+1,因为他是第一个,所以他回答了bummi。 – Wodzu

+1

你应该接受最好的答案。如果你认为它有帮助,你也应该赞扬bummi。不要害羞。但最重要的是,不仅仅是谁最快。注意我并不是说我的答案就是你应该接受的答案。我已经多次说过了。接受最好的答案。如果有人有更好的答案。接受。 –

+0

感谢您的评论。正在考虑你的答案的质量。问题是,对我来说,bummi的代码足以了解我犯了什么错误。 – Wodzu

相关问题