gpt4 book ai didi

class - DXE7 : "type A = type B" and var x (of type A):= A. create 导致 E2010 不兼容类型编译错误。为什么?

转载 作者:行者123 更新时间:2023-12-02 08:57:04 29 4
gpt4 key购买 nike

A. 问​​题的简短总结:

type
A = class(TObject)
end;

B = type A;

编译器错误 E2010 incompatible types: 'B' and 'A'显示,当您以以下样式实例化 B 类的变量时:
var
TheB: B;
begin
TheB:= B.Create;
..

我可以通过删除第二种“类型”来避免这个问题,所以声明是标准的:
type
A = class(TObject)
end;

B = A;

但在我看来,即使使用第二个“类型”,错误也不应该出现,因为没有直接使用 A(第二个“类型”告诉编译器将两个类视为个体,详见 http://docwiki.embarcadero.com/RADStudio/Seattle/en/Declaring_Types)。有人可以解释一下,由于什么原因错误忽略了我的意见? (o;

B. 完整的历史和更复杂的细节:

首先:错误:
[dcc32 Fehler] gboDHL.pas(165): E2010 Inkompatible Typen: 'Origin' und 'CountryType'(在英语中的意思是“不兼容的类型”),

出现在以下代码行中:
AShipmentOrder.Shipment.Shipper.Address.Origin:= DHL_geschaeftskundenversand_api_2.Origin.Create;

现在是背景:

我尝试与“新的”DHL Geschäftskundenversand API v2.2 通信,它仍然使用 SOAP 来创建发货订单。 DHL_geschaeftskundenversand_api_2是从集成的 delphi xe7 WSDL 生成器为该服务完全生成的单元。 AShipmentOrder是代表请求的顶级 xml 节点的实例。

“Origin”类以这种方式实现/生成:
type    
CountryType = class(TRemotable)
private
Fcountry: country2;
Fcountry_Specified: boolean;
FcountryISOCode: countryISOType;
Fstate: state;
Fstate_Specified: boolean;
Fcountry_: country;
Fcountry__Specified: boolean;
FcountryISOCode_: countryISOType;
Fstate_: state2;
Fstate__Specified: boolean;
procedure Setcountry(Index: Integer; const Acountry2: country2);
function country_Specified(Index: Integer): boolean;
procedure Setstate(Index: Integer; const Astate: state);
function state_Specified(Index: Integer): boolean;
procedure Setcountry_(Index: Integer; const Acountry: country);
function country__Specified(Index: Integer): boolean;
procedure Setstate_(Index: Integer; const Astate2: state2);
function state__Specified(Index: Integer): boolean;
published
property country: country2 Index (IS_OPTN) read Fcountry write Setcountry stored country_Specified;
property countryISOCode: countryISOType read FcountryISOCode write FcountryISOCode;
property state: state Index (IS_OPTN) read Fstate write Setstate stored state_Specified;
property country_: country Index (IS_OPTN) read Fcountry_ write Setcountry_ stored country__Specified;
property countryISOCode_: countryISOType read FcountryISOCode_ write FcountryISOCode_;
property state_: state2 Index (IS_OPTN) read Fstate_ write Setstate_ stored state__Specified;
end;

Origin = type CountryType; { "http://dhl.de/webservice/cisbase"[GblElm] }
AShipmentOrder.Shipment.Shipper.Address 的“属性(property)”来源以这种方式实现/生成:
type
NativeAddressType = class(TRemotable)
...
published
...
property Origin: Origin Index (IS_OPTN or IS_REF) read FOrigin write SetOrigin stored Origin_Specified;
...
end;

如果不清楚,让我说,'AShipmentOrder.Shipment.Shipper.Address' 属于 NativeAddressType

我在 Windows 10 64 位上使用 Delphi XE7,编译为 32 位。

delphi WSDL 生成器有不同的问题,我之前必须处理这些问题,而且在输出中属性名称与类名称相同确实不是“好”,但这似乎是不可更改的。
“Origin”类不是生成单元中唯一被命名为其所属属性的类,但仅当这样的类被实现为时才会发生错误
type
A = type B

我试图找到那个特殊声明变体的描述,但这很难,因为关键字被使用得太频繁了。

http://www.delphibasics.co.uk/RTL.asp?Name=Type我找到了以下解释:
1.type Name = Existing type  
Refers to an existing type, such as string by a new Name.
 
2.type Name = type Existing type  
This has the same effect as above, but ensures that at run time, variables of this type are identified by their new type name, rather than the existing type name.

如果我理解正确,这意味着在我的示例中,类 Origin不再标识为 CountryType , 但作为 Origin .那应该没问题,因为属性 Origin被声明为类 Origin .

在继续尝试理解该问题时,我手动将生成单元中的类“Origin”重命名为 OriginType(delphi 将该后缀“Type”与该单元中的其他几个类一起使用,不清楚,为什么它没有使用它原始类型)。之后,我可以排除名称冲突,因为现在错误是
[dcc32 Fehler] gboDHL.pas(165): E2010 Inkompatible Typen: 'OriginType' und 'CountryType'
由于发生该错误,似乎没有任何理由。

经过几个小时没有任何想法后,我发现了这个 Embarcadero WIKI 条目: http://docwiki.embarcadero.com/RADStudio/Seattle/en/Declaring_Types

在阅读和思考之后,我明白了, A = type B 中的“类型”在这种情况下没有必要,因为不需要以 B 类以外的其他方式处理 A 类,所以我在生成的单元中手动删除了它,现在它工作正常。

我也明白,检查了生成器中的一个特殊选项以防止“名称冲突”。如果这个选项没有被选中,这个问题也应该得到解决(但也许其他一些问题会出现(o;)。

也许这有助于某人在外面度过更多的时间而不是解决这样的问题(o;

但最后,我不明白这里有什么问题,因为所有属性都是“Origin”类型,后来是“OriginType”,这个类型也是用 Origin.Create创建的。之后使用 OriginType.Create .因此,除了“Origin”/“OriginType”的类声明外,从未使用过“CountryType”。在我看来,这不应该导致这个问题,但确实如此。

有人可以解释一下吗?

先感谢您

最佳答案

您将获得:E2010 Incompatible types: 'Tb' and 'Ta' ,这可能看起来很奇怪:

type
Ta = class
end;
Tb = type Ta;
var
b: Tb;
begin
b := Tb.Create; // E2010 Incompatible types: 'Tb' and 'Ta'
end.
TaTb是两种截然不同的类型。

来自 Type Compatibility您可以看到列出的条件都没有表明这两种不同的类型是兼容的。

Type Compatibility

Every type is compatible with itself. Two distinct types are compatible if they satisfy at least one of the following conditions.

  • They are both real types.
  • They are both integer types.
  • One type is a subrange of the other.
  • Both types are subranges of the same type.
  • Both are set types with compatible base types.
  • Both are packed-string types with the same number of characters.
  • One is a string type and the other is a string, packed-string, or Char type.
  • One type is Variant and the other is an integer, real, string, character, or Boolean type.
  • Both are class, class-reference, or interface types, and one type is derived from the other.
  • One type is PAnsiChar or PWideChar and the other is a zero-based character array of the form array[0..n] of PAnsiChar or PWideChar.
  • One type is Pointer (an untyped pointer) and the other is any pointer type.
  • Both types are (typed) pointers to the same type and the {$T+} compiler directive is in effect.
  • Both are procedural types with the same result type, the same number of parameters, and type-identity between parameters in corresponding positions.


因此,编译器错误的原因是:当您调用 Tb.Create 时,编译器将其标识为 Ta.Create并且因为 b是一个独特的不兼容类型,它不被接受。

您可以称其为缺陷,但它遵循严格的类型规则,并且可以很容易地纠正,如下所示。

声明 Tb = class(Ta)将解决自 Tb 以来的编译器错误源自 Ta .

同时声明 Tb = Ta将解决编译器错误,因为它们将表示相同的类型(不是两种不同的类型),因此分配兼容。

关于class - DXE7 : "type A = type B" and var x (of type A):= A. create 导致 E2010 不兼容类型编译错误。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42317081/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com