Дельфи 2010:Новый RTTI, присваивающий свойству произвольное значение.
-
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)
Но для меня это тот же вопрос, что и для Франсуа.Почему вы хотите установить свойство со значением неправильного типа данных?