Part V: Other General Items Of Interest
Attributes
Each representation of a member has a property named Attributes. Do not be fooled, this attribute is not used to specify attributes (metadata) that have been placed on a member.
Attributes are of the enum type MemberAttributes which is a flags enum:
| Member |
Binary Representation |
C# |
VB.NET |
| AccessMask | 1111 | 0000 | 0000 | 0000 | | |
| Assembly | 0001 | 0000 | 0000 | 0000 | internal | Internal |
| FamilyAndAssembly | 0010 | 0000 | 0000 | 0000 | private* | Internal* |
| Family | 0011 | 0000 | 0000 | 0000 | protected | Protected |
| FamilyOrAssembly | 0100 | 0000 | 0000 | 0000 | protected internal | Protected Internal |
| Private | 0101 | 0000 | 0000 | 0000 | private | Private |
| Public | 0110 | 0000 | 0000 | 0000 | public | Public |
| VTableMask** | 0000 | 0000 | 1111 | 0000 | | |
| New | 0000 | 0000 | 0001 | 0000 | new | Shadows |
| ScopeMask | 0000 | 0000 | 0000 | 1111 | | |
| Abstract | 0000 | 0000 | 0000 | 0001 | abstract | MustInherit MustOverride |
| Final | 0000 | 0000 | 0000 | 0010 | sealed* | NotInheritable* |
| Static | 0000 | 0000 | 0000 | 0011 | static | Shared |
| Override | 0000 | 0000 | 0000 | 0100 | override | Overrides |
| Const | 0000 | 0000 | 0000 | 0101 | const | Const |
| Overloaded | 0000 | 0001 | 0000 | 0000 | N/A | Overloaded |
* Created only if the member also uses MemberAttributes.Override.
Important: Zero a mask before using any of the flags. Take the following code for example:
// Use the masks to set the access and scope flag spaces to
// undefined.
myMember.Attributes &=
~MemberAttributes.AccessMask & ~MemberAttributes.ScopeMask;
// Bitwise set the Assembly and Static flags.
myMember.Attributes |=
MemberAttributes.Assembly | MemberAttributes.Static;
This code would cause the member to be declared as internal and static (shared).
Should we fail to change the Attributes property, the member would be declared simply as a private member.
Note: In order to specify that a member is virtual, simply zero its scope mask:
member.Attributes &= ~MemberAttributes.ScopeMask;
Type Attributes
The ugly part about the attributes we discussed is the use of the
System.Reflection.TypeAttributes enum with
CodeTypeDeclarations.
To specify that the type is either abstract (MustInherit) or sealed (NotInheritable), you should set CodeTypeDeclaration's
TypeAttributes property.
e.g.:
// My class is abstract!
myDecl.TypeAttributes |= TypeAttributes.Abstract;
Custom Attributes
In order to place an attribute on a member (i.e. a class deriving from
System.Attribute), one should use the
CustomAttributes property.
e.g.:
myMember.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(ObsoleteAttribute));
Snippet Classes
If you have knowledge of the specific language in which the code is about to be generated, you can include Code Snippets, which basically give the ability to insert free text into the generated file.
This should be used only in harsh conditions, when all else fails, because it rather destroys the whole meaning of an independent code document object model. Examples:
CodeSnippetTypeMember,
CodeSnippetCompileUnit and
CodeSnippetExpression.
Really. Don't use it.