Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

"Проверка и создание пользовательского Variant для типа TBcd с помощью TValue.AsVariant"

Delphi , Синтаксис , Типы и Переменные

Статья: "Проверка и создание пользовательского Variant для типа TBcd с помощью TValue.AsVariant"

В данной статье мы рассмотрим вопрос о проверке и создании пользовательского Variant для типа TBcd с помощью метода TValue.AsVariant. Мы также предложим решение этой проблемы, а затем рассмотрим альтернативное решение.

Контекст: Дмитрий Б. задал вопрос о том, как проверить наличие соответствующего пользовательского типа Variant для определенного записи (record) типа и вызвать создание соответствующего пользовательского значения Variant при вызове TValue.AsVariant для типа TBcd. Он столкнулся с ошибкой "Неверное преобразование класса" при попытке выполнить это.

Рейми Лебо, другой участник дискуссии, объяснил, что TValue progettato per mimare solo le conversione che il compilatore stesso può eseguire implicitamente. I Custom variant non rientrano in questa area. Non ci sono conversione implicite tra TBcd e Variant, devi usare funzioni esplicite (ad esempio VarFMTBcdCreate() e VarToBcd()), che TValue non può chiamare internamente per te. Questo è il motivo per cui ottieni l’errore "Nessun cast di classe valido".

Решение: Чтобы проверить наличие соответствующего пользовательского типа Variant для определенного записи (record) типа и вызвать создание соответствующего пользовательского значения Variant при вызове TValue.AsVariant, вы можете использовать следующий подход:

  1. Создайте пользовательский тип Variant для типа TBcd, если он еще не создан.
  2. Проверьте, является ли текущий тип Variant пользовательским типом Variant для типа TBcd с помощью TRttiType и TRttiProperty.
  3. Если это так, вызовите TValue.AsVariant, чтобы создать соответствующее пользовательское значение Variant.

Пример кода на Object Pascal (Delphi):

uses
  System.SysUtils,
  System.Types,
  TypInfo,
  System.UITypes,
  System.Classes,
  System.Variants,
  Data.FmtBcd;

type
  TFMTBcdVariantType = record
    VarData: TBcd;
    constructor Create(const AValue: TBcd);
  end;

constructor TFMTBcdVariantType.Create(const AValue: TBcd);
begin
  VarData := AValue;
end;

type
  TListItemObj = class(TPersistent)
  private
    FSecondName: String;
    FFirstName: String;
    FAge: Integer;
    FBigUInt: UInt64;
    FFmtBcd: TBcd;
  public
    property FirstName: String read FFirstName write FFirstName;
    property SecondName: String read FSecondName write FSecondName;
    property Age: Integer read FAge write FAge;
    property BigUInt: UInt64 read FBigUInt write FBigUInt;
    property FmtBcd: TBcd read FFmtBcd write FFmtBcd;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  LType: TRttiType;
  AllProps: TArray<TRttiProperty>;
  Prop: TRttiProperty;
  RttiContext: TRttiContext;
  ValValue: TValue;
  VarValue: Variant;
  FmtBcdVarType: TRttiType;

  ListItem: TListItemObj;
begin
  ListItem := TListItemObj.Create;
  with ListItem do
  begin
    FirstName := 'P';
    SecondName := 'C';
    Age := 33;
    BigUInt := 12345678900987654321;
    FmtBcd := 112233445566778899.000011;
  end;

  RttiContext := TRttiContext.Create;
  LType := RttiContext.GetType(TListItemObj);
  AllProps := LType.GetProperties();

  FmtBcdVarType := RttiContext.GetType(TFMTBcdVariantType);

  for Prop in AllProps do
  begin
    ValValue := Prop.GetValue(ListItem);

    if Prop.Type = FmtBcdVarType then
      VarValue := VarFMTBcdCreate(ValValue.AsType(TFMTBcdVariantType).VarData)
    else
      VarValue := ValValue.AsVariant;
  end;

  ListItem.Free;
end;

В этом примере мы создаем пользовательский тип Variant для типа TBcd, называемый TFMTBcdVariantType. Затем мы проверяем, является ли текущий тип Variant пользовательским типом Variant для типа TBcd с помощью TRttiType и TRttiProperty. Если это так, мы вызываем VarFMTBcdCreate(), чтобы создать соответствующее пользовательское значение Variant. В противном случае мы просто вызываем TValue.AsVariant.

Альтернативное решение: В качестве альтернативного решения вы можете использовать функции VarFMTBcdCreate() и VarToBcd(), чтобы явно преобразовать тип TBcd в Variant и наоборот. Это избавит вас от необходимости создавать пользовательский тип Variant для типа TBcd и проверять его наличие перед вызовом TValue.AsVariant.

Пример кода на Object Pascal (Delphi):

uses
  System.SysUtils,
  System.Types,
  TypInfo,
  System.UITypes,
  System.Classes,
  System.Variants,
  Data.FmtBcd;

type
  TListItemObj = class(TPersistent)
  private
    FSecondName: String;
    FFirstName: String;
    FAge: Integer;
    FBigUInt: UInt64;
    FFmtBcd: TBcd;
  public
    property FirstName: String read FFirstName write FFirstName;
    property SecondName: String read FSecondName write FSecondName;
    property Age: Integer read FAge write FAge;
    property BigUInt: UInt64 read FBigUInt write FBigUInt;
    property FmtBcd: TBcd read FFmtBcd write FFmtBcd;
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  LType: TRttiType;
  AllProps: TArray<TRttiProperty>;
  Prop: TRttiProperty;
  RttiContext: TRttiContext;
  ValValue: TValue;
  VarValue: Variant;

  ListItem: TListItemObj;
begin
  ListItem := TListItemObj.Create;
  with ListItem do
  begin
    FirstName := 'P';
    SecondName := 'C';
    Age := 33;
    BigUInt := 12345678900987654321;
    FmtBcd := 112233445566778899.000011;
  end;

  RttiContext := TRttiContext.Create;
  LType := RttiContext.GetType(TListItemObj);
  AllProps := LType.GetProperties();

  for Prop in AllProps do
  begin
    ValValue := Prop.GetValue(ListItem);

    if Prop.Type.Name = 'TBcd' then
      VarValue := VarFMTBcdCreate(ValValue.AsType(TBcd))
    else
      VarValue := ValValue.AsVariant;
  end;

  ListItem.Free;
end;

В этом примере мы явно проверяем, является ли текущий тип Variant

Создано по материалам из источника по ссылке.

Статья: "Проверка и создание пользовательского Variant для типа TBcd с помощью TValue.AsVariant"


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Типы и Переменные ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-09-19 07:19:51/0.00337815284729/0