Sigh...
Sigh...
type
Default = class(TCustomAttribute)
public
Value: T;
constructor Create(const aValue: T);
function AsString:String;
end;
...
TMyEdit = class(TEditor)
protected
[Default(200)] // [dcc32 Error]: E2029 ']' expected but '<' found
SupplierNo: TIntegerEdit;
//...
end;
#halfbaked
type
Default
public
Value: T;
constructor Create(const aValue: T);
function AsString:String;
end;
...
TMyEdit = class(TEditor)
protected
[Default
SupplierNo: TIntegerEdit;
//...
end;
#halfbaked
Trying to get fancy eh? :P
ReplyDeleteNo, trying to stay type safe :P
ReplyDeleteEdit: I.e. ensure that attribute values can be validated at compile time - yeah I can do a ton of custom attributes or variations on constructors, but that's not quite as nice.
I guess this will be my substitute solution.
ReplyDeletetype
Def = class(TCustomAttribute)
protected
Value: TValue;
public
constructor Create(const aValue: String); overload;
constructor Create(const aValue: Integer); overload;
constructor Create(const aValue: Double); overload;
// and so forth
end;
constructor Def.Create(const aValue: String);
begin
Value := TValue.From(aValue);
end;
constructor Def.Create(const aValue: Integer);
begin
Value := TValue.From(aValue);
end;
constructor Def.Create(const aValue: Double);
begin
Value := TValue.From(aValue);
end;
#reimplementingtheweel ?
ReplyDeleteJust use http://docwiki.embarcadero.com/Libraries/Seattle/en/System.Classes.DefaultAttribute
Didn't know about that one.
ReplyDeleteHmm: Variant vs TValue ...
Lars Fosdal Since the input is limited to a handful of simple types Variant works fine imo. TValue is only useful when all possible types need to be handled (i.e. Rtti) and it needs to be completely strict in what can be converted.
ReplyDeleteThe challenge is the enumerated types. TMyOptions = (Option1, Option2, Option3);
ReplyDeletehmmm... how would that be type-safe at compile-time?
ReplyDeleteEven if it worked, wouldn't the compiler compile this without errors?
[Default('hello bug')]
SupplierNo: TIntegerEdit;
Eric Grange It would. Afaik not even C# has the possibility to put some custom restrictions where an attribute can be applied. I think they handle it mostly through some things like Fx or similar (hello static code analysis)
ReplyDeleteWhat if you do this?
ReplyDelete...
DefaultIntegerAttribute = class(Default);
...
[DefaultInteger(200)]
SupplierNo: TIntegerEdit;
...
Allen Bauer That works but still ceremony of adding DefaultWhateverTypeAttribute type definitions for everything.
ReplyDeleteEspecially since code insight in attributes does not work. Now that would be great: type [Def followed by ctrl+space and woosh lists all known attributes starting with Def.
Well, I never said it was a perfect solution :)...
ReplyDeleteAnd, yes, codeinsight for attributes would be awesome... It, however, is a little tricky given that an attribute doesn't have to exist. It was done this way to such that only attributes actually "seen" during a compile are attached.. others are simply ignored (no "unknown identifier errors").
Of course, it could still be done by only showing attributes that are currently visible in scope, as you would expect.
I presume this is already entered into the Quality Portal?
Allen Bauer Since I had that idea when writing the comment, no, but here you go: https://quality.embarcadero.com/browse/RSP-12918
ReplyDeleteStefan Glienke Excellent. Thanks. I've gone ahead and opened/validated it internally. As always, no promises on the time frame.
ReplyDeleteAllen Bauer What about Generics syntax in attributes - is that something you would consider supporting?
ReplyDeleteLars Fosdal It is something to consider, however it does create another level of complication... almost an order of magnitude of more complication.
ReplyDeleteWhile a lot of these things seem tiny, they can lead to an O n2 problem... We get a lot of requests for such-and-such language feature... along with a requirement that it take exactly 0 extra cycles to implement it. IOW, add this cool feature but don't you dare think about slowing down the compiler one bit because I'll compare it with last version and complain bitterly when you added 500ms to my 5 minute compile cycle!
Not that anyone here would ever think of doing that... nope :).