2010-05-26 12 views
5

Obecnie tworzę opakowania mydła dla niektórych funkcji Delphi, dzięki czemu możemy z łatwością używać ich z PHP, C# i Delphi.Jak odsłonić typ zestawu Delphi przez Soap

Zastanawiam się, jaki jest najlepszy sposób na odsłonięcie zestawów.

type 
    TCountry  = (countryUnknown,countryNL,countryD,countryB,countryS,countryFIN,countryF,countryE,countryP,countryPl,countryL); 
    TCountrySet = set of TCountry; 

function GetValidCountrySet(const LicensePlate:string; const PossibleCountriesSet:TCountrySet):TCountrySet; 

Jestem obecnie owijając go tak dla serwera mydła:

type 
    TCountryArray = array of TCountry; 

function TVehicleInfo.GetValidCountrySet(const LicensePlate:string; const PossibleCountriesSet:TCountryArray):TCountryArray; 

To działa, ale muszę napisać dużo kodu bezużyteczne i brzydkie przekonwertować Sets -> i tablice tablice -> zestawy.

Czy jest łatwiejszy, bardziej elegancki lub bardziej ogólny sposób na zrobienie tego?

Odpowiedz

2

Możesz użyć TypInfo i użyć odrobiny sprytnego rzucania.

uses TypInfo; 

type 
    TCountry = (cnyNone, cnyNL, cnyD, cnyGB, cnyF, cnyI); 
    TCountrySet = set of TCountry; 

    TCountryArray = array of TCountry; 
    TEnumIntegerArray = array of Integer; 
    TEnumByteArray = array of Byte; 

function GetEnumNamesInSet(const aTypeInfo: PTypeInfo; const aValue: Integer; const aSeparator: string = ','): string; 
var 
    IntSet: TIntegerSet; 
    i: Integer; 
begin 
    Result := ''; 
    Integer(IntSet) := aValue; 
    for i := 0 to SizeOf(Integer) * 8 - 1 do begin 
    if i in IntSet then begin 
     if Result <> '' then begin 
     Result := Result + ','; 
     end; 
     Result := Result + GetEnumName(aTypeInfo, i); 
    end; 
    end; 
end; 

function SetToIntegerArray(const aTypeInfo: PTypeInfo; const aValue: Integer): TEnumIntegerArray; 
var 
    IntSet: TIntegerSet; 
    i: Integer; 
begin 
    SetLength(Result, 0); 
    Integer(IntSet) := aValue; 
    for i := 0 to SizeOf(Integer) * 8 - 1 do begin 
    if i in IntSet then begin 
     SetLength(Result, Length(Result) + 1); 
     Result[Length(Result) - 1] := i; 
    end; 
    end; 
end; 

function SetToByteArray(const aTypeInfo: PTypeInfo; const aValue: Byte): TEnumByteArray; 
var 
    IntSet: TIntegerSet; 
    i: Integer; 
begin 
    SetLength(Result, 0); 
    Integer(IntSet) := aValue; 
    for i := 0 to SizeOf(Byte) * 8 - 1 do begin 
    if i in IntSet then begin 
     SetLength(Result, Length(Result) + 1); 
     Result[Length(Result) - 1] := i; 
    end; 
    end; 
end; 

Następnie użyj jako:

procedure TEnumForm.FillMemo; 
var 
    Countries: TCountrySet; 
// EIA: TEnumIntegerArray; 
    EBA: TEnumByteArray; 
    CA: TCountryArray; 
    i: Integer; 
    cny: TCountry; 
begin 
    Countries := [cnyNL, cnyD]; 
    CountriesMemo.Text := GetEnumNamesInSet(TypeInfo(TCountry), Byte(Countries)); 
// if SizeOf(TCountry) > SizeOf(Byte) then begin 
// EIA := SetToIntegerArray(TypeInfo(TCountry), Integer(Countries)); 
// end else begin 
    EBA := SetToByteArray(TypeInfo(TCountry), Byte(Countries)); 
// end; 
    CountriesMemo.Lines.Add('===='); 
    CountriesMemo.Lines.Add('Values in Array: '); 
// if SizeOf(TCountry) > SizeOf(Byte) then begin 
// CA := TCountryArray(EIA); 
// end else begin 
    CA := TCountryArray(EBA); 
// end; 
    for i := 0 to Length(CA) - 1 do begin 
    CountriesMemo.Lines.Add(IntToStr(Ord(CA[i]))); 
    end; 
    CountriesMemo.Lines.Add('===='); 
    CountriesMemo.Lines.Add('Names in Array: '); 
// if SizeOf(TCountry) > SizeOf(Byte) then begin 
// CA := TCountryArray(EIA); 
// end else begin 
    CA := TCountryArray(EBA); 
// end; 
    for i := 0 to Length(CA) - 1 do begin 
    cny := CA[i]; 
    CountriesMemo.Lines.Add(GetEnumName(TypeInfo(TCountry), Ord(cny))); 
    end; 
end; 

Musisz wybrać właściwą odlewu na podstawie wielkości wyliczenia TCountry. Jeśli ma 8 członków, będzie to bajt, większy i będzie liczbą całkowitą. W każdym razie Delphi będzie skarżyła się na obsadę Bajtów (krajów) lub Integer (krajów), jeśli źle zrobisz.

Uwaga: Funkcje teraz przyjmują TypeInfo of derountry - elementy zestawu TCountrySet. Można je zmienić, aby uzyskać TypeInfo (TCountrySet). Oznaczałoby to jednak, że funkcje będą działać, jakie elementy są w zestawie, a ja po prostu nie miałem jeszcze czasu ani ochoty to zrobić.

1

Mydło powinno być używane w sposób niezależny od platformy i języka - zaprojektowałbym wszystkie obiekty transferu danych (DTO) oparte na prostych typach, np. array of string, bez funkcji specyficznych dla języka. Następnie zmapuj DTO do pasujących obiektów biznesowych. To również da ci "warstwę antykorupcyjną".

Powiązane problemy