Дельфи 2010:Новый RTTI, присваивающий свойству произвольное значение.

StackOverflow https://stackoverflow.com/questions/1603427

  •  05-07-2019
  •  | 
  •  

Вопрос

TRTTIProperty.SetValue( ) принимает экземпляр TValue, но если предоставленный экземпляр TValue основан на другом типе, то это свойство, все портится.

Например.

TMyObject = class
published
  property StringValue: string read FStringValue write FStringValue;
end;

procedure SetProperty(obj: TMyObject);
var
  context: TRTTIContext;
  rtti: TRTTIType;
  prop: TRTTIProperty;
  value: TValue;
begin
  context := TRTTIContext.Create;
  rtti := context.GetType(TMyObject);
  prop := rtti.GetProperty('StringValue');
  value := 1000;
  prop.SetValue(obj, value);
end;

Попытка привести значение к строке также не сработает.

prop.SetValue(obj, value.AsString);
prop.SetValue(obj, value.Cast(prop.PropertyType.Handle));

Есть идеи, как это решить?

ОБНОВЛЯТЬ:

Некоторые из вас задаются вопросом, почему я хочу присвоить строке целое число, и я попытаюсь объяснить.(На самом деле, более вероятно, что я хочу присвоить строку целому числу, но это не так важно...)

Я пытаюсь создать общего «посредника» между графическим интерфейсом и моделью.Я хочу каким-то образом привязать поле textedit к свойству.Вместо того, чтобы создавать такого посредника для каждой моей модели, я надеялся, что новая штука RTTI/TValue сотворит для меня какое-то волшебство.

Я также новичок в дженериках, поэтому не уверен, как дженерики могли бы помочь.Можно ли во время выполнения создать экземпляр обобщенного типа с динамически определяемым типом или компилятор должен знать об этом?

Например.

TMyGeneric<T> = class
end;

procedure DoSomething( );
begin
  prop := rtti.getProperty('StringValue');
  mygen := TMyGeneric<prop.PropertyType>.Create;
  //or
  mygen := TMyGeneric<someModel.Class>.Create;
end;

Возможно, эпоха волшебства еще не наступила...Думаю, я справлюсь с парочкой больших корпусов...

Это было полезно?

Решение

TValue не является вариантом.Вы можете прочитать только тот тип данных, который «вы» в него вложили.

TValue.Cast не работает, поскольку имеет ту же семантику, что и неявное приведение типов.Вы не можете присвоить целое число строке и наоборот.Но вы можете присвоить целое число вещественному числу или int64.

Другие советы

Не могу сейчас попробовать, но я бы написал:

  value := '1000'; 
  prop.SetValue(obj, value);

пытаться

prop.SetValue(obj, value.ToString)

Но для меня это тот же вопрос, что и для Франсуа.Почему вы хотите установить свойство со значением неправильного типа данных?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top