Delphi 2010: новый RTTI, устанавливающий свойство value в произвольное значение - PullRequest
4 голосов
/ 22 октября 2009

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

* 1003 Е.Г. *

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));

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

UPDATE:

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

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

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

1019 * Е.Г. *

TMyGeneric<T> = class
end;

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

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

Ответы [ 3 ]

5 голосов
/ 22 октября 2009

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

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

0 голосов
/ 22 октября 2009

1001 * попробовать *

prop.SetValue(obj, value.ToString)

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

0 голосов
/ 22 октября 2009

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

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