Class Reference as Property

2020-05-24 06:05发布

问题:

Google is useless for these sorts of searches, because you get hundreds of millions of results absolutely none of which relate to the specific question.

The question is simply this:

  • Is it possible to have a Class Reference Property in Delphi?
  • If so, how?

Here's what I've tried...

type

  TMyObject = class
    // ...
  end;

  TMyObjectClass = class of TMyObject

  TMyObjectA = class(TMyObject)
    // specifics here
  end;

  TMyObjectB  =class(TMyObject)
    // specifics here
  end;

  TMyComponent = class(TComponent)
  private
    FObjectType: TMyObjectClass;
  published
    property ObjectType: TMyObjectClass read FObjectType write FObjectType;
  end;

The above code compiles fine, however the Object Inspector does not show the ObjectType property at all.

My objective here (if you haven't already guessed) is to make it so that I can select a class descendant from a specific base class, to make the same component behave in a different way.

I want to do it this way so that the component doesn't need to know about the sub-classes directly (it needs to be fully modular).

Let me just make this bit clear: I cannot use an Enum to choose between the sub-class types as the component cannot directly link to the sub-class types (It's simply not possible in this particular case)

Anyway... thanks in advance!

回答1:

You can find all classes that descend from a particular base class: Delphi: At runtime find classes that descend from a given base class? and make this a special property with list of values using TPropertyEditor.



回答2:

If you were going to do this then you would need to provide a property editor. The IDE does not come with property editors for class type properties. You would also need to handle .dfm persistence. You would write the class type out to the .dfm file as a string and when the .dfm file is read, you would need to fixup the reference. New style RTTI could do that.

However, I don't think any of this is actually viable for the following reason. Your design time code runs in a package inside the IDE and does not have access to the class types in the active project in the IDE. Those class types only exist when that project runs. So the ObjectType property in the code in your question cannot be assigned to anything meaningful in the design time package. Well, you could use it for classes defined in the VCL and any other packages installed in your IDE but I rather imagine you'd want to use it on classes defined in the active project.

I think all this means that you should instead use a simple string property and fixup the class type references only at runtime.