Ludzie pragną czasami się rozstawać, żeby móc tęsknić, czekać i cieszyć się z powrotem.
Set this property to the value Value.
• The result is O, an instance of the attribute class T that has been initialized with the positional-argument-list P and the named-argument-list N.
17.4 Reserved attributes
A small number of attributes affect the language in some way. These attributes include:
Copyright Microsoft Corporation 1999-2000. All Rights Reserved.
245
C# LANGUAGE REFERENCE
• System.AttributeUsageAttribute, which is used to describe the ways in which an attribute class can be used.
• System.ConditionalAttribute, which is used to define conditional methods.
• System.ObsoleteAttribute, which is used to mark a member as obsolete.
17.4.1 The AttributeUsage attribute
The AttributeUsage attribute is used to describe the manner in which the attribute class can be used.
A class that is decorated with the AttributeUsage attribute must derive from System.Attribute, either directly or indirectly. Otherwise, a compile-time error occurs.
[AttributeUsage(AttributeTargets.Class)]
public class AttributeUsageAttribute: System.Attribute
{
public AttributeUsageAttribute(AttributeTargets validOn) {…}
public AttributeUsageAttribute(AttributeTargets validOn,
bool allowMultiple,
bool inherited) {…}
public bool AllowMultiple { virtual get {…} virtual set {…} }
public bool Inherited { virtual get {…} virtual set {…} }
public AttributeTargets ValidOn { virtual get {…} }
}
public enum AttributeTargets
{
Assembly
= 0x0001,
Module
= 0x0002,
Class
= 0x0004,
Struct
= 0x0008,
Enum
= 0x0010,
Constructor = 0x0020,
Method
= 0x0040,
Property
= 0x0080,
Field
= 0x0100,
Event
= 0x0200,
Interface
= 0x0400,
Parameter
= 0x0800,
Delegate
= 0x1000,
All = Assembly | Module | Class | Struct | Enum | Constructor |
Method | Property | Field | Event | Interface | Parameter |
Delegate,
ClassMembers = Class | Struct | Enum | Constructor | Method |
Property | Field | Event | Delegate | Interface,
}
17.4.2 The Conditional attribute
The Conditional attribute enables the definition of conditional methods. The Conditional attribute indicates a condition in the form of a pre-processing identifier. Calls to a conditional method are either included or omitted depending on whether this symbol is defined at the point of the call. If the symbol is defined, then the method call is included if the symbol is undefined, then the call is omitted.
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class ConditionalAttribute: System.Attribute
{
public ConditionalAttribute(string conditionalSymbol) {…}
246
Copyright Microsoft Corporation 1999-2000. All Rights Reserved.
Chapter 17 Attributes
public string ConditionalSymbol { get {…} }
}
A conditional method is subject to the following restrictions:
• The conditional method must be a method in a class-declaration. A compile-time error occurs if the Conditional attribute is specified on an interface method.
• The conditional method must return have a return type of void.
• The conditional method must not be marked with the override modifier. A conditional method may be marked with the virtual modifier. Overrides of such a method are implicitly conditional, and must not be explicitly marked with a Conditional attribute.
• The conditional method must not be an implementation of an interface method. Otherwise, a compile-time error occurs.
Also, a compile-time error occurs if a conditional method is used in a delegate-creation-expression. The example
#define DEBUG
class Class1
{
[Conditional("DEBUG")]
public static void M() {
Console.WriteLine("Executed Class1.M");
}
}
class Class2
{
public static void Test() {
Class1.M();
}
}
declares Class1.M as a conditional method. Class2's Test method calls this method. Since the pre-processing symbol DEBUG is defined, if Class2.Test is called, it will call M. If the symbol DEBUG had not been defined, then Class2.Test would not call Class1.M.
It is important to note that the inclusion or exclusion of a call to a conditional method is controlled by the pre-processing identifiers at the point of the call. In the example
// Begin class1.cs
class Class1
{
[Conditional("DEBUG")]
public static void F() {
Console.WriteLine("Executed Class1.F");
}
}
// End class1.cs
// Begin class2.cs
#define DEBUG
Copyright Microsoft Corporation 1999-2000. All Rights Reserved.
247
C# LANGUAGE REFERENCE
class Class2
{
public static void G {
Class1.F();
// F is called
}
}
// End class2.cs
// Begin class3.cs
#undef DEBUG
class Class3
{
public static void H {
Class1.F();
// F is not called
}
}
// End class3.cs
the classes Class2 and Class3 each contain calls to the conditional method Class1.F, which is conditional based on the presence or absence of DEBUG. Since this symbol is defined in the context of Class2 but not Class3, the call to F in Class2 is actually made, while the call to F in Class3 is omitted.
The use of conditional methods in an inheritance chain can be confusing. Calls made to a conditional method through base, of the form base.M, are subject to the normal conditional method call rules. In the example class Class1
{
[Conditional("DEBUG")]
public virtual void M() {
Console.WriteLine("Class1.M executed");
}
}
class Class2: Class1
{
public override void M() {