Delphi:在Variants数组中传递TObject

时间:2009-04-15 11:39:06

标签: delphi variant tobject

我有一个程序需要一个TObject类型的参数,如下所示:

MyProcedure (const AValue : TObject);

我有一个Variant数组,我正在循环调用该过程,如下所示:

  for i:=0 to High(myArray) do
    MyProcedure (myArray[i]);

编译器给出错误说:“不兼容的类型:TObject和Variant”。

我该怎么做才能解决这个问题?

更多信息:到目前为止,我一直在变量数组中传递简单类型(字符串,数字,日期)(数组通常是不同类型的混合 - 我最终通过它们作为数据库存储过程的参数)。现在我还需要(在某些情况下)传递TObject。

传递值的最合适的数据类型/结构是什么,它可以包含简单类型和对象?我想我可以创建自己的TParam类型,它有两个字段,但我不确定确切的语法。有人有这方面的例子吗?

4 个答案:

答案 0 :(得分:8)

Variant不能保存对象,它只能包含整数和字符串等基本类型。

我建议将您的数组更改为您想要的类型而不是变体。如果您不确定所需的对象类型,则创建一个TObject数组或数组将保存的对象的最低基类。

答案 1 :(得分:3)

您不能存储普通对象是一种变体。但是你可以存储接口。

var
  v : Variant;
  i : IInterface;

begin
  v := i; // Works perfectly;
end.

查看变体的类型:

varEmpty    = $0000; { vt_empty        0 }
varNull     = $0001; { vt_null         1 }
varSmallint = $0002; { vt_i2           2 }
varInteger  = $0003; { vt_i4           3 }
varSingle   = $0004; { vt_r4           4 }
varDouble   = $0005; { vt_r8           5 }
varCurrency = $0006; { vt_cy           6 }
varDate     = $0007; { vt_date         7 }
varOleStr   = $0008; { vt_bstr         8 }
varDispatch = $0009; { vt_dispatch     9 }
varError    = $000A; { vt_error       10 }
varBoolean  = $000B; { vt_bool        11 }
varVariant  = $000C; { vt_variant     12 }
varUnknown  = $000D; { vt_unknown     13 }
//varDecimal  = $000E; { vt_decimal     14 } {UNSUPPORTED as of v6.x code base}
//varUndef0F  = $000F; { undefined      15 } {UNSUPPORTED per Microsoft}
varShortInt = $0010; { vt_i1          16 }
varByte     = $0011; { vt_ui1         17 }
varWord     = $0012; { vt_ui2         18 }
varLongWord = $0013; { vt_ui4         19 }
varInt64    = $0014; { vt_i8          20 }
varUInt64   = $0015; { vt_ui8         21 }

如果你真的想要,你可以将TObject转换为Pointer to Integer并存储它。但我不确定这是不是你真正想要的。

答案 2 :(得分:1)

我的第一反应是问你为什么要把TObject存储在一个变种列表中,但假设你有充分的理由!

如果您设法将TObject实例放在数组中,那么您可能会将指针放在Tobject上。在这种情况下,您需要做的是将Variant / Integer作为TObject进行类型转换,例如

for i:=0 to High(myArray) do
    MyProcedure (TObject(myArray[i]));

这应该可行,但是与任何类型转换一样,由您来确保myArray [i]实际上是指向TObject实例的指针或可能发生的可怕事情。

你确定TList不会做你想做的事吗?变体实际上是用于存储基本类型,例如字符串,整数,浮点数,布尔值而不是对象。

答案 3 :(得分:0)

我认为创建一个带有Variant变量和TOBject变量的TParam并不是一个好主意。类似的东西:

Tobject = record
  prim: Variant;
  obj: TObject;
end

会起作用,但对我来说似乎很麻烦。帕斯卡不是一种语言类型的语言,我不会尝试将其视为一种语言。我建议:

创建另一个函数来处理Variant,以及

MyProcedure (const AValue : TObject);

也有

MyProcedure (const AValue : Variant);

单独处理您的数据。或者创建一个定义数据输入的记录,例如,不要让变体和对象的TParam具有类似的东西:

TStoredProcParm = record
  name: String;
  bought: TDateTime;
end;

等等。也许你有这么多不同的数据,变量/对象路由是最好的,但它似乎有点维护头痛 - 当你的其他代码传递一个Variant数组时,你怎么知道哪个变量是哪个以及如何使用每个变量他们在你的存储过程中?