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 to SomeField
-
_my_longer_property
becomes MyLongerProperty
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;
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;
}