3

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

MyProcedure (const AValue : TObject);

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

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

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

我能做些什么来解决这个问题?

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

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

4

4 回答 4

8

Variant 不能包含对象,它只能包含原始类型,例如整数和字符串。

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

于 2009-04-15T11:56:48.977 回答
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 并存储它。但我不确定这是否是你真正想要的。

于 2009-04-15T11:54:03.587 回答
1

我的第一反应是问为什么要将 TObjects 存储在变体列表中,但假设您有充分的理由!

如果您首先设法将 TObject 实例放置在 Array 中,那么您可能将指针放置在了 Tobject 中。在这种情况下,您需要做的是将 Variant/Integer 类型转换为 TObject 例如

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

这应该有效,但是与任何类型转换一样,您需要确保 myArray[i] 实际上是指向 TObject 实例的指针,否则可能会发生可怕的事情。

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

于 2009-04-15T11:50:29.057 回答
0

我认为用 Variant 变量和 TOBject 变量创建 TParam 不是一个好主意。就像是:

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

会工作,但对我来说似乎很乱。Pascal 不是一种动态类型的语言,我不会尝试将其视为一种语言。我会建议:

创建另一个函数来处理变体,以及拥有

MyProcedure (const AValue : TObject);

也有

MyProcedure (const AValue : Variant);

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

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

等等。也许您有太多不同的数据,以至于变体/对象路由是最好的,但这似乎有点让人头疼 - 当您的其他代码通过 Variant 数组时,您如何知道哪个变体是哪个以及如何使用每个它们在您的存储过程中?

于 2009-04-15T12:25:19.220 回答