2009-04-15 6 views
3

다음과 같은 TObject 유형의 매개 변수를 예상하는 프로 시저가 있습니다.델파이 : 변종의 배열에 TObject 전달

MyProcedure (const AValue : TObject); 

이 프로 시저를 호출 할 때 반복되는 Variant 배열이 있습니다.

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

컴파일러에서 "호환되지 않는 유형 : TObject 및 Variant"라는 오류 메시지를 표시합니다.

이 문제를 해결하려면 어떻게해야합니까?

추가 정보 : 지금까지는 변형 배열에 간단한 유형 (문자열, 숫자, 날짜)을 전달했습니다. 배열은 일반적으로 다른 유형의 혼합입니다. 데이터베이스 저장 프로 시저). 이제 TObject를 전달해야합니다 (특정 경우).

값을 전달하는 데 가장 적합한 데이터 형식/구조는 무엇이며 간단한 형식과 개체를 모두 포함 할 수 있습니까? 둘 다 필드가있는 내 자신의 TParam 형식을 만들 수 있지만 정확한 구문을 잘 모르겠습니다 것 같습니다. 누구나 이것의 예가 있습니까?

+0

관련 항목 : http://stackoverflow.com/questions/366329/why-cant-delphi-variants-hold-objects –

답변

8

변형은 개체를 보유 할 수 없으며 정수 및 문자열과 같은 기본 유형 만 포함 할 수 있습니다.

변형이 아닌 원하는 유형으로 배열을 변경하는 것이 좋습니다. 원하는 객체 유형을 모르는 경우 TObject 배열 또는 배열에서 보유 할 객체의 가능한 가장 낮은 기본 클래스를 만듭니다.

+0

Delphi의 사용자 지정 변형 (TCustomVariantType 자손)은 개체를 보유 할 수 있습니다. VCL에서도 이와 같은 예가 있습니다 (SqlTimSt.TSQLTimeStampVariantType, FMTBcd.TFMTBcdVariantType 참조). –

1

첫 번째 반응은 왜 변형 목록에 TObjects를 저장하고 있는지 묻는 것입니다. 그러나 좋은 이유가 있다고 가정하면됩니다.

처음에 TObject 인스턴스를 배열에 배치 할 수 있었다면 포인터를 Tobject에 배치했을 것입니다. 당신이 당신에게 달려있는 타입 캐스팅과 마찬가지로 그러나에서 myArray [내가] 실제로 포인터가 있는지 확인하기 위해, 예를 들어

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

이 작동해야 TObject의로 변형/정수 타입 변환되어 수행해야하는 경우에 TObject 인스턴스 또는 끔찍한 일이 발생할 수 있습니다.

TList가 원하는 것을 수행하지 않을 것이라고 확신합니까? 변형은 실제로 string, integer, float, boolean with Objects와 같은 기본 유형을 저장하기위한 것입니다.

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의는 정수의 포인터와 그 저장합니다. 그러나 그것이 당신이 정말로 원하는 것인지 확실하지 않습니다.

+0

Gamecat에 동의합니다. 개체를 변형으로 전달해야하는 경우 인터페이스 사용을 고려할 것입니다. . – skamradt

0

Variant 변수 TOBject 변수를 사용하여 TParam을 만드는 것이 좋습니다. 다음과 같음 :

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

작동하지만 매우 나빠질 것 같습니다. 파스칼은 역 동성으로 타이핑 된 언어가 아니며 나는 그것을 하나로서 취급하려하지 않는다.

가 변형을 처리 할 수있는 다른 기능을 만들기 때문에뿐만 아니라

MyProcedure (const AValue : TObject); 

MyProcedure (const AValue : Variant); 

을 가지고 별도로 데이터를 처리 갖는 나도 건의 할 것입니다. 그래서

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

과 : 또는 변형 및 개체의 TParam를하는 대신, 예를 들어, 데이터 입력을 정의하는 레코드를 생성 같은 것을 가지고있다. 어쩌면 variant/object 라우트가 가장 좋은 데이터가 너무 많을 지 모르지만, 유지 보수의 어려움처럼 보일 것입니다 - 다른 코드가 Variant의 배열을 전달 받으면 어떻게 변형이되는지, 각 변형을 사용하는 방법을 어떻게 알 수 있습니까? 당신의 저장된 프로 시저에서 그들 중?

+0

"지저분한"TParam 레코드에 대한 귀하의 요지를 봅니다. 그러나 어떤 방법을 사용해야 하는지를 알 수있는 방법이 있으므로이 프로젝트에서 나에게 가장 좋은 해결책 일 것입니다. TObject 값은 거의 사용되지 않습니다. – ObiWanKenobi