【发布时间】:2021-01-31 15:15:48
【问题描述】:
我想对属性使用属性,但是这些属性偶尔会在继承的类中发生变化。这是一个示例代码(非常简化):
TBaseClass = class(TObject)
private
FFoo: string;
published
[BaseAttirib('hello')]
property Foo: string read FFoo;
end;
TChildClass = class(TBaseClass)
published
[BaseAttirib('good bye')]
property Foo;
end;
当我使用 RTTI 遍历属性时,Foo 属性在 GetProperties 数组中出现两次:
var
xObj: TObject;
xType: TRttiType;
xProp: TRttiProperty;
begin
// FContext is a TRttiContext, already created, not included in this sample
xObj := TChildClass.Create;
try
xType := FContext.GetType(xObj.ClassType);
for xProp in xType.GetProperties do
begin
if not (xProp.Visibility in [mvPublished]) then
Continue;
Memo1.lines.add(xProp.Name + ' = ' + xProp.GetValue(xObj).AsString);
end;
finally
FreeAndNil(xObj);
end;
end;
这是输出:
Foo = TChildClass
Foo = TChildClass
在基类中将属性可见性更改为 public 可以解决问题,但在我的情况下这是不可接受的,因为我必须一一增加此属性可见性以在所有子类中发布。
我的问题是如何防止 Foo 属性重复出现,或者至少有什么方法可以在这些重复项之间决定哪个来自基类,哪个来自子类?
更新,更多解释:
我们有一个算法,它将对象的所有已发布属性保存到导出文件中,并且 BaseAttrib 属性包含一些必要的信息。 假设我有一个 TBaseClass 实例和一个 TChildClass 实例,对于 TBaseClass,我想在输出文件中看到“hello”,而对于 TChildClass,我想在输出文件中看到“good bye”。
另外值得一提的是,如果我不创建 TBaseClass 的实例并将 Foo 的可见性降低到 public,然后在我发布 Foo 属性的地方引入一个新的可实例化类,我将丢失 Foo 属性的属性(在TBaseClass)。因此,如果我有 100 个后代类,但我只想更改一个类中的属性值,我仍然需要将相同的属性(使用原始参数)复制到剩余的 99 个类中。
我想指出,这是一个非常简化的示例,我必须在现有的复杂类结构中引入属性,并且我想以最少的油漆方式做到这一点,而无需更改/重写所有类继承.
如果我可以避免/管理属性重复,那将是最好的方法,这就是我寻找这种解决方案的原因。
【问题讨论】:
-
通常的做法是不要发布两次
-
@Andreas Rejbrand:不,我还没有,快看看,谢谢!
-
@David Heffernan:谢谢!这让我变成了一只悲伤的熊猫。我很好奇 IDE 对象检查器是如何解决这个问题的?
-
@Andreas Rejbrand:该主题描述了相同的问题,但仅解释了为什么会发生这种情况,但不会提供解决方案。无论如何,这很有帮助,再次感谢。
标签: delphi