-
Notifications
You must be signed in to change notification settings - Fork 89
Accessor macros
When writing classes, you very often need to write code like:
mutable some_field : int;
public SomeField : int
{
get { some_field }
}
You can automate this common pattern using the Accessor
macro:
using Nemerle.Utility;
[Accessor (SomeField)] mutable some_field : int;
Here, the Accessor macro creates a read-only property named SomeField
,
which accesses the field {some_field}. Accessor properties are
read-only by default.
You can also omit the name, in which case the property name will be based on the field name. The name will be capitalized, and underscores removed:
-
some_field
is changed toSomeField
-
_my_longer_property
becomesMyLongerProperty
This helps make property names more uniform and readable.
There are three flag options available for this macro. The first is for specifying that the accessor is internal, not public. This limits accessibility to callers within the same assembly:
[Accessor (SomeField, flags = Internal)]
mutable some_field : int;
// Equivalent to:
mutable internal_field : int = 0 ;
internal InternalField : int
{
get { internal_field }
}
There are similar Protected
, Virtual
and Override
options.
The WantSetter
option is used to generate a set property:
[Accessor (SomeField, flags = WantSetter)]
mutable some_field : int;
// Equivalent to:
public SomeField : int
{
get { some_field }
set { some_field = value }
}
Flags can be combined:
[Accessor(SomeField, flags = Internal | WantSetter)]
mutable some_field : int;
Sometimes, it is necessary to add some custom attributes to the generated property. Option attributes is used to solve this challenge:
[Accessor (SomeField, attributes(System.CLSCompliant(true), AnyOther))]
mutable some_field : int;
// Equivalent to:
[System.CLSCompliant(true), AnyOther]
public SomeField : int
{
get { some_field }
}
There are cases when you want to use field of enum type (marked with System.Flags attribute) to store a set of flags. But you otherwise want this stuff to be exposed via boolean properties. For example:
class SomeClass
{
[System.Flags]
enum MyFlags {
| Is42 = 0x0001
| Kopytko = 0x0002
| DeepThought = 0x0004
}
mutable state : MyFlags;
public Is42 : bool
{
get { state %&& MyFlags.Is42 }
set {
if (value)
state |= MyFlags.Is42
else
state &= ~MyFlags.Is42;
}
}
// same for Kopytko and DeepThought
}
There is FlagAccessor
macro to automate this:
using Nemerle.Utility;
class SomeClass {
[System.Flags]
enum MyFlags {
| Is42 = 0x0001
| Kopytko = 0x0002
| DeepThought = 0x0004
}
[FlagAccessor (Is42, flags = WantSetter)]
[FlagAccessor (Kopytko, flags = WantSetter)]
[FlagAccessor (DeepThought, flags = WantSetter)]
mutable state : MyFlags;
}
To shorten it even more you can group several flags in one macro invocation:
using Nemerle.Utility;
class SomeClass
{
[System.Flags]
enum MyFlags {
| Is42 = 0x0001
| Kopytko = 0x0002
| DeepThought = 0x0004
}
[FlagAccessor (Is42, Kopytko, DeepThought, flags = WantSetter)]
mutable state : MyFlags;
}