// interface
iccItem =
class
ID : String;
DATA : Variant;
constructor Create( _id : String; _data : Variant);
end;
iccDynamicObject =
class
private
FItems : TList;
function locate( _id : String) : iccItem;
public
constructor Create();
destructor Destroy(); override;
public
procedure define( _id : String; _dta : Variant);
//function get( _ndx : DWORD) : Variant; overload;// link to original data
function get( _id : String) : Variant; overload;
public
property Items[_id : String] : Variant read get write define; default;
end;
// implementation
{ iccDynamicObject }
constructor iccItem.Create( _id : String; _data : Variant);
begin
ID := _id;
DATA := _data;
end;
function iccDynamicObject.locate( _id : String) : iccItem;
var ndx : integer;
tmp : iccItem;
begin
result := nil;
for ndx := 0 to FItems.Count - 1 do
begin
tmp := iccItem( FItems[ndx]);
if tmp.ID = _id
then begin
result := tmp;
exit;
end;
end;
end;
constructor iccDynamicObject.Create();
begin
FItems := TList.Create();
end;
destructor iccDynamicObject.Destroy();
begin
{$MESSAGE 'clear here'}
FItems.Destroy();
inherited;
end;
procedure iccDynamicObject.define( _id : String; _dta : Variant);
var tmp : iccItem;
begin
tmp := locate( _id);
if tmp = nil
then FItems.Add( iccItem.Create( _id, _dta) )
else tmp.DATA := _dta;
end;
//function iccDynamicObject.get( _ndx : DWORD) : Variant;
//begin
// result.vPointer := nil;
//end;
function iccDynamicObject.get( _id : String) : Variant;
var tmp : iccItem;
begin
tmp := locate( _id);
if tmp = nil
then result.vaNull := true
else result := locate( _id).DATA;
end;
// using
procedure TForm1.FormCreate(Sender: TObject);
var c : iccDynamicObject;
begin
c := iccDynamicObject.Create;
c['asd'] := 123;
c.Destroy;
end;
Set breakpoint in DELPHI 2010 at iccDynamicObject.define() -> tmp := locate( _id); will cause @Project Project1.exe raised exception class EVariantBadVarTypeError with message 'Invalid variant type'.@
在iccdynamicobjecter .define() -> tmp:= locate(_id)在DELPHI 2010中设置断点;将导致@Project Project1。exe使用消息“无效变体类型”.@引发异常类EVariantBadVarTypeError
Code was tested in DELPHI 7, and this problem was not encountered!
在DELPHI 7中测试了代码,没有遇到这个问题!
ps. code was rewritten in delphi-7 style without in-class types for demonstrating a problem...
代码以delphi7格式重写,不使用类内类型来演示问题……
SOLVED -> Do not use in-class generic types, such as
已解决的->不使用类内泛型类型,例如
classDef<_type> =
class
type
// this
internalClass<_anotherType> =
class
private
FSomething : _anotherType;
end;
// or this one
internalClass2 =
class
private
FSomething : _type;
end;
private
FInternalClass : internalClass<_type>;
FInternalClass2 : internalClass;
end;
Such things will procure debugger or compiler to do UNEXCECTED THINGS!!! Code compiles and work correctly. But in my case, with Unit growth code become unstable and coerce me to make some code-refactoring, just a little, but more than inconvenient...
这样的事情将促使调试器或编译器去做未经授权的事情!!代码编译并正确工作。但在我的例子中,随着单元增长代码变得不稳定,迫使我进行一些代码重构,虽然只是一点点,但却非常不方便……
You are Noticed :)))
你注意到:)))
4 个解决方案
#1
5
This is a known bug in D2010 which has been reported in QualityCentral and fixed in XE.
这是D2010中已知的一个bug,它在QualityCentral中被报道,并在XE中被修复。
#2
1
Try assigning tmp := nil;
in the locate method next to where you assign nil to result. If this resolves the exception, I'll explain why.
尝试分配tmp:= nil;在将nil赋值给result的locate方法中。如果这解决了异常,我将解释原因。
#3
1
This problem occured by unexpected debugger or compiler behavior, and such behavior was caused by bugs in Delphi 2010 (they might be fixed in Delphi XE, as David Heffernan
mentioned).
这个问题是由意外的调试器或编译器行为引起的,这种行为是由Delphi 2010中的错误引起的(如David Heffernan所提到的,这些错误可能在Delphi XE中得到修复)。
I have only one conclusion: Do not use in-class generic types, such as:
我只有一个结论:不要使用类内泛型类型,例如:
classDef<_type> =
class
type
// this
internalClass<_anotherType> =
class
private
FSomething : _anotherType;
end;
// or this one
internalClass2 =
class
private
FSomething : _type;
end;
private
FInternalClass : internalClass<_type>;
FInternalClass2 : internalClass;
end;
Such things will cause the debugger or compiler to do unexpected things. The code compiles and works correctly. But in my case, with Unit growth code becoming unstable it has forced me to do some code-refactoring.
这些操作将导致调试器或编译器执行意外的操作。代码编译并正确工作。但是在我的例子中,随着单元增长代码变得不稳定,它迫使我进行一些代码重构。
#4
0
Did you try with a New VCL Forms Applications, including the code you provided?
I did...
您是否尝试了新的VCL表单应用程序,包括您提供的代码?我做了……
1- setting the break point does not do anything (no harm either), because you have to read your item to call get(_id)
2- I added a line to that effect:
1-设置断点没有任何作用(也没有什么害处),因为您必须读取项目以调用get(_id) 2-我为此添加了一行:
c['asd'] := 123;
i := c['asd']; // <=== added
c.Destroy;
3- the breakpoint worked as expected, without any exception
断点按预期工作,无一例外
So I'm guessing there is something else going on....
所以我猜有别的....
#1
5
This is a known bug in D2010 which has been reported in QualityCentral and fixed in XE.
这是D2010中已知的一个bug,它在QualityCentral中被报道,并在XE中被修复。
#2
1
Try assigning tmp := nil;
in the locate method next to where you assign nil to result. If this resolves the exception, I'll explain why.
尝试分配tmp:= nil;在将nil赋值给result的locate方法中。如果这解决了异常,我将解释原因。
#3
1
This problem occured by unexpected debugger or compiler behavior, and such behavior was caused by bugs in Delphi 2010 (they might be fixed in Delphi XE, as David Heffernan
mentioned).
这个问题是由意外的调试器或编译器行为引起的,这种行为是由Delphi 2010中的错误引起的(如David Heffernan所提到的,这些错误可能在Delphi XE中得到修复)。
I have only one conclusion: Do not use in-class generic types, such as:
我只有一个结论:不要使用类内泛型类型,例如:
classDef<_type> =
class
type
// this
internalClass<_anotherType> =
class
private
FSomething : _anotherType;
end;
// or this one
internalClass2 =
class
private
FSomething : _type;
end;
private
FInternalClass : internalClass<_type>;
FInternalClass2 : internalClass;
end;
Such things will cause the debugger or compiler to do unexpected things. The code compiles and works correctly. But in my case, with Unit growth code becoming unstable it has forced me to do some code-refactoring.
这些操作将导致调试器或编译器执行意外的操作。代码编译并正确工作。但是在我的例子中,随着单元增长代码变得不稳定,它迫使我进行一些代码重构。
#4
0
Did you try with a New VCL Forms Applications, including the code you provided?
I did...
您是否尝试了新的VCL表单应用程序,包括您提供的代码?我做了……
1- setting the break point does not do anything (no harm either), because you have to read your item to call get(_id)
2- I added a line to that effect:
1-设置断点没有任何作用(也没有什么害处),因为您必须读取项目以调用get(_id) 2-我为此添加了一行:
c['asd'] := 123;
i := c['asd']; // <=== added
c.Destroy;
3- the breakpoint worked as expected, without any exception
断点按预期工作,无一例外
So I'm guessing there is something else going on....
所以我猜有别的....