Delphi:在变体数组中传递 TObject

发布于 2024-07-16 19:43:31 字数 525 浏览 6 评论 0原文

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

MyProcedure (const AValue : TObject);

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

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

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

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

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

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

I have a procedure that expects a parameter of type TObject, something like this:

MyProcedure (const AValue : TObject);

I have an array of Variant that I'm looping through to call the procedure, something like this:

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

The compiler gives an error saying: "Incompatible types: TObject and Variant".

What can I do to get around this?

More information: Up until now, I have been passing simple types (strings, numbers, dates) in variant arrays (the arrays are typically a mix of different types -- I'm eventually passing them as parameters to a database stored procedure). Now I need to also (in certain cases) pass a TObject.

What is the most appropriate data type/structure to pass the values, that can hold both simple types and objects? I guess I could create my own TParam type that has a field for both, but I am not sure of the exact syntax. Anyone has an example of this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

纸短情长 2024-07-23 19:43:31

Variant 不能容纳对象,它只能包含基本类型,例如整数和字符串。

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

A Variant cannot hold objects, it can only contain primitive types such as integer and string.

I would suggest changing your array to be of the type you want rather than variant. If you are not sure of the object type you want then create an array of TObject or the lowest possible base class of the objects that your array will hold.

鸩远一方 2024-07-23 19:43:31

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

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 转换为指向整数的指针并将其存储。 但我不确定这是否是你真正想要的。

You can't store plain objects is a variant. But you can store interfaces.

var
  v : Variant;
  i : IInterface;

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

Look at the types for the variant:

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 }

You can if you really want, cast TObject to Pointer to Integer and store that. But i'm not sure if that's what you really want.

绮烟 2024-07-23 19:43:31

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

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

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

这应该可以工作,但是与任何类型转换一样,您需要确保 myArray[i] 实际上是指向 TObject 实例或可怕事物的指针可能发生。

您确定 TList 不会执行您想要的操作吗? 变体实际上是为了存储基本类型,例如字符串、整数、浮点数、布尔值,而不是对象。

My first reaction is to ask why you are storing TObjects in a list of variants, but assuming you have a good reason!

If you managed to place your TObject instance in the Array in the first place then you probably placed the pointer to the Tobject. In that case what you need to do is typecast the Variant/Integer as a TObject eg

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

This should work, however as with any typecasting it is up to you to ensure that myArray[i] is actually a pointer to a TObject instance or horrible things might happen.

Are you sure a TList would not do what you want. A variant is really meant to store fundamental types such as string, integer, float, boolean not Objects.

安穩 2024-07-23 19:43:31

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

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

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

创建另一个函数来处理 Variant,这样也可以

MyProcedure (const AValue : TObject);

单独

MyProcedure (const AValue : Variant);

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

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

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

I don't think it's a good idea to create a TParam with a Variant variable a TOBject variable. Something like:

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

Would work but it seems very messy to me. Pascal is not a dyanmically typed language and I woudn't try and treat it as one. I would suggest either:

Create another function to handle Variant, so as well as having

MyProcedure (const AValue : TObject);

also have

MyProcedure (const AValue : Variant);

and handle your data seperately. Or create a record that defines your data inputs, for example instead of having TParam of variant and object have something like:

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

and so on. Maybe you have so much different data that the variant/object route is the best but it seems like a bit of a maintenance headache - when your other code gets passed an array of Variant how do you know which variant is which and how to use each of them in your Stored proc?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文