Thursday, September 20, 2007

DN4DP#15: .NET only: Attributes support

This post continues the series of The Delphi Language Chapter teasers from Jon Shemitz’ .NET 2.0 for Delphi Programmers book.

The previous post covered support for .NET Boxing operations. We continue with the .NET specific topic of Attributes support.

Note that I do not get any royalties from the book and I highly recommend that you get your own copy – for instance at Amazon.

"Attributes support

Any proper .NET language must support associating attributes to classes and members, and Delphi is no exception. The attribute syntax closely resembles C#. The attribute class name (with or without the Attribute suffix) is placed inside square brackets prior to the element you want to apply it to. The attribute name may be followed by parens with constructor parameters and property assignments. Normally, the compiler will figure out what element the attribute belongs to by its context, but you can prefix the attribute name with a target indicator and colon, such as assembly:.

type
[MyCustom(Age=42, Name='Frank Borland')]
TMyObject = class

[MyCustomAttribute('Ida Emilie', 10)]
procedure Foo;
end;

[assembly:MyCustomAttribute('Thea Ulrikke', 3)]

Sample code

unit AttributesSupportU;

interface

type
[AttributeUsage(AttributeTargets.All)]
MyCustomAttribute = class(Attribute)
public
Name: string;
Age: Integer;
constructor Create; overload;
constructor Create(AName: string); overload;
constructor Create(AName: string; AAge: integer); overload;
function ToString: string; override;
end;
type
[MyCustom(Age=42, Name='Frank Borland')]
TMyObject = class
[MyCustomAttribute('Ida Emilie', 10)]
procedure Foo;
end;

[assembly:MyCustomAttribute('Thea Ulrikke', 3)]
procedure Test;

implementation

uses
SysUtils,
System.Reflection;

{ TMyCustomAttribute }

constructor MyCustomAttribute.Create;
begin
Create('', 0);
end;

constructor MyCustomAttribute.Create(AName: string);
begin
Create(AName, 0);
end;

constructor MyCustomAttribute.Create(AName: string; AAge: integer);
begin
inherited Create;
Name := AName;
Age := AAge;
end;

function MyCustomAttribute.ToString: string;
begin
Result := Format('%s, Name=%s, Age=%d', [inherited ToString, Name, Age]);
end;

{ TMyObject }

procedure TMyObject.Foo;
begin
Writeln('TMyObject.Foo');
end;

procedure Test;
var
T: System.Type;
O: TObject;
M: MemberInfo;
A: Assembly;
begin
T := TMyObject.ClassInfo;
Writeln(T.ToString);
for O in T.GetCustomAttributes(False) do
writeln(' ', O.ToString);
Writeln;
M := T.GetMethod('Foo');
Writeln(M.ToString);
for O in M.GetCustomAttributes(False) do
writeln(' ', O.ToString);
Writeln;
A := T.Assembly;
Writeln(A.ToString);
for O in A.GetCustomAttributes(False) do
writeln(' ', O.ToString);
end;

end.

"

No comments:



Copyright © 2004-2007 by Hallvard Vassbotn