|
array of const |
Top Previous Next |
|
What is translated > Types > Arrays > Array parameters > array of const "Array of const" parameters look similar to open array parameters.
procedure foo(Args : array of const);
However, while all elements of an open array have the same type, elements of different types can be passed as an array of const. Indeed the array of const is an open array of TVarRec elements and TVarRec is a variant type which which can contain the single values of different types.
The pre-translated C# version of essential parts of the Delphi RTL includes a C# counterpart to TVarRec
public struct TVarRec { public int VType { get; private set; } public object Value { get; private set; }
private TVarRec(int type, object value) { VType = type; Value = value; } ...
The conversion of a type to TVarRec and vice versa, the conversion back to a variable of the corresponding type, is done automatically as long as the conversions are unambiguous. However, there are not as many types in C# as there are in Delphi that can be stored in a TVarRec. For example, in C# it is not possible to distinguish between AnsiString and UnicodeString. If this distinction is necessary, it can be made manually in C# by calling the corresponding TVarRec methods, e.g. FromAnsiString(sa) or ToAnsiStringValue().
procedure foo(Args : array of const)
->
public static void foo(params TVarRec[] Args)
If the option to create pure C# code is enabled object is used instead of TVarRec.
procedure foo(Args : array of const)
->
public static void foo(object[] Args)
A following complex example is from: https://stackoverflow.com/questions/19532228/how-do-i-build-an-array-of-const
function VarRecToStr( AVarRec : TVarRec ) : string; const bool : array[boolean] of string = ('False', 'True'); begin case AVarRec.VType of vtInteger: result := IntToStr(AVarRec.VInteger); vtBoolean: result := bool[AVarRec.VBoolean]; vtChar: result := AVarRec.VChar; vtExtended: result := FloatToStr(AVarRec.VExtended^); vtString: result := AVarRec.VString^; // vtPointer vtPChar: result := AVarRec.VPChar; vtObject: result := AVarRec.VObject.ClassName; vtClass: result := AVarRec.VClass.ClassName; vtWideChar: result := AVarRec.VWideChar; //vtPWideChar: Result := AVarRec.PWideChar^; vtAnsiString: result := string(AVarRec.VAnsiString); vtCurrency: result := CurrToStr(AVarRec.VCurrency^); vtVariant: result := string(AVarRec.VVariant^); //vtInterface: (VInterface: Pointer); vtWideString: result := string(AVarRec.VWideString); //vtInt64: Result := AVarRec.PInt64^; vtUnicodeString: result := string(AVarRec.VUnicodeString); //Reserved1: NativeInt; //VType: Byte; else result := ''; end; end;
function VarArrayToStr( AVarArray : array of const ) : string; var i : Integer; begin result := ''; for i := 0 to High(AVarArray) do result := result + VarRecToStr( AVarArray[i] ); end;
procedure foo; var s : string; begin s := VarArrayToStr([1, true, 'a', 1.2, 'hello']); end;
The conversion to an object is implicit and it's called boxing. The reverse unboxing operation, the conversion of an objet to the contained value type, is explicit, that means for each value type the an according cast has to be done.
public static string VarRecToStr(object AVarRec) { string result = string.Empty; string[] bools = new string[2/*# boolean*/]{"False", "True"}; switch(Type.GetTypeCode(AVarRec.GetType())) { case vtInteger: result = (((int)AVarRec)).ToString(); break; case vtBoolean: result = bools[Convert.ToInt32(((bool)AVarRec))]; break; case vtChar: result = ((char)AVarRec).ToString(); break; case vtExtended: result = FloatToStr(((double)AVarRec)); break; case vtString: result = ((string)AVarRec); break; // vtPointer case vtPChar: result = ((string)AVarRec); break; case vtObject: result = AVarRec.ClassName; break; case vtClass: result = AVarRec.ClassName; break; case vtWideChar: result = ((char)AVarRec).ToString(); break; //vtPWideChar: Result := AVarRec.PWideChar^; case vtAnsiString: result = ((string) ((string)AVarRec)); break; case vtCurrency: result = CurrToStr(((decimal)AVarRec)); break; case vtVariant: result = ((string) AVarRec); break; //vtInterface: (VInterface: Pointer); case vtWideString: result = ((string) ((string)AVarRec)); break; //vtInt64: Result := AVarRec.PInt64^; case vtUnicodeString: result = ((string) ((string)AVarRec)); break; //Reserved1: NativeInt; //VType: Byte; default: result = ""; break; } return result; }
public static string VarArrayToStr(object[] AVarArray) { string result = string.Empty; int i = 0; int stop = 0; result = ""; for(stop = AVarArray.Length - 1 /*# High(AVarArray) */, i = 0; i <= stop; i++) { result = result + VarRecToStr(AVarArray[i]); } return result; }
public static void foo() { string s = string.Empty; s = VarArrayToStr(new object[]{1, true, 'a', 1.2D, "hello"}); }
There are ambiguous cases however. For example in C# the different string types are nor distinguished. Delphi2C# cannot decide, which string case is the best. Here manual post-Processing is necessary.
|
|
This page belongs to the Delphi2C# Documentation |
Delphi2C# home Content |