Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a Variant property have default value?

I've written a component who has a Variant property for which I would like to set a default value.

TMyComponent = class(TComponent)
private
  FVariantValue : Variant;
published
  property VariantValue : Variant read FVariantValue write FVariantValue default False;
end;

On compilation, I get the following error on the VariantValue property line:

E2026 Constant expression expected

Doing the same thing with a Boolean property doesn't cause any kind of error.

I read a little bit of documentation but I didn't find nothing about Variant properties default values.

like image 327
Fabrizio Avatar asked Apr 13 '17 14:04

Fabrizio


People also ask

Can a property have default value?

The defaultValue property sets or returns the default value of a text field. Note: The default value is the value specified in the HTML value attribute.

Can we set default value in property C#?

You can assign the default value using the DefaultValueAttribute attribute, as shown below.

What is the default value of the property?

Explanation: The default value is the value specified in the HTML value attribute. The difference between the defaultValue and value property, is that defaultValue contains the default value, while value contains the current value after some changes have been made.

How do I set default value in property?

Right-click the control that you want to change, and then click Properties or press F4. Click the All tab in the property sheet, locate the Default Value property, and then enter your default value. Press CTRL+S to save your changes.


2 Answers

Be careful here. The default directive does not do anything to set the value of the property itself. It only affects whether or not the value is explicitly saved in the .dfm file. If you specify a default value for a property you still have to ensure that the constructor initializes the backing field to that value.

Properties : Storage Specifiers

When saving a component's state, the storage specifiers of the component's published properties are checked. If a property's current value is different from its default value (or if there is no default value) and the stored specifier is True, then the property's value is saved. Otherwise, the property's value is not saved.

Note: Property values are not automatically initialized to the default value. That is, the default directive controls only when property values are saved to the form file, but not the initial value of the property on a newly created instance.

This is just a hint to the component streaming system that it doesn't need to store this value explicitly in the .dfm - your part of the contract is to ensure that you actually initialize the backing field to that value. The appropriate place to do this type of initialization is in the component's constructor:

constructor TMyComponent.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FVariantValue := False;
end;

That said, False is a boolean, not a variant, so it cannot be used as a constant expression of Variant type. Since a variant is a complex type it cannot be expressed as a single constant and, therefore, cannot have a default property.

Per Remy, if you want to ensure that the variant is not saved in the .dfm file when the backing variant is False, you can use the stored directive with a parameterless method which returns False when the variant evaluates to a boolean False. For example :

 property VariantValue : Variant read FVariantValue write FVariantValue stored IsVariantValueStored;

where

function TMyComponent.IsVariantValueStored : Boolean;
begin
  Result := not VarIsType(FVariantValue, varBoolean);
  if not Result then
    Result := FVariantValue;
end;
like image 126
J... Avatar answered Oct 18 '22 01:10

J...


Variant properties cannot have default values.

like image 25
David Heffernan Avatar answered Oct 18 '22 01:10

David Heffernan