Scrigroup - Documente si articole

Username / Parola inexistente      

Home Documente Upload Resurse Alte limbi doc  
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml


Attributes - Attribute classes

C sharp



+ Font mai mare | - Font mai mic



Attributes

Much of the C# language enables the programmer to specify declarative information about the entities defined in the program. For example, the accessibility of a method in a class is specified by decorating it with the method-modifiers public, protected, internal, and private.



C# enables programmers to invent new kinds of declarative information, called attributes. Programmers can then attach attributes to various program entities, and retrieve attribute information in a run-time environment. For instance, a framework might define a HelpAttribute attribute that can be placed on certain program elements (such as classes and methods) to provide a mapping from those program elements to documentation.

Attributes are defined through the declaration of attribute classes (17.1), which may have positional and named parameters (17.1.2). Attributes are attached to entities in a C# program using attribute specification (17.2), and can be retrieved at run-time as attribute instances (17.3).

Attribute classes

A class that derives from the abstract class System.Attribute, whether directly or indirectly, is an attribute class.The declaration of an attribute class defines a new kind of attribute that can be placed on a declaration. By convention, attribute classes are named with a suffix of Attribute. Uses of an attribute may either include or omit this suffix.

Attribute usage

The AttributeUsage attribute (17.4.1) is used to describe how an attribute class can be used.

AttributeUsage has a positional parameter (17.1.2) that enables an attribute class to specify the kinds of declarations on which it can be used. The example

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public class SimpleAttribute: Attribute

defines an attribute class named SimpleAttribute that can be placed only on class-declarations and interface-declarations. The example

[Simple] class Class1

[Simple] interface Interface1

shows several uses of the Simple attribute. Although this attribute is defined with the name SimpleAttribute, when it is used the Attribute suffix may be omitted, resulting in the short name Simple. The example above is semantically equivalent to:

[SimpleAttribute] class Class1

[SimpleAttribute] interface Interface1

AttributeUsage has a named parameter (17.1.2) called AllowMultiple that indicates whether the attribute can be specified more than once for a given entity. If AllowMultiple for an attribute class is true, then it is a multi-use attribute class, and can be specified more than once on an entity. If AllowMultiple for an attribute class is false or unspecified, then it is a single-use attribute class, and can be specified at most once on an entity.

The example

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class AuthorAttribute: Attribute

public string Name
}

private string name;
}

defines a multi-use attribute class named AuthorAttribute. The example

[Author('Brian Kernighan'), Author('Dennis Ritchie')]
class Class1

shows a class declaration with two uses of the Author attribute.

AttributeUsage has a named parameter called Inherited that indicates whether the attribute, when specified on a base class, is also inherited by classes that derive from that base class. If Inherited for an attribute class is true, then that attribute is inherited. If Inherited for an attribute class is false or it is unspecified, then that attribute is not inherited.

Positional and named parameters

Attribute classes can have positional parameters and named parameters. Each public instance constructor for an attribute class defines a valid sequence of positional parameters for the attribute class. Each non-static public read-write field and property for an attribute class defines a named parameter for the attribute class.

The example

[AttributeUsage(AttributeTargets.Class)]
public class HelpAttribute: Attribute

public string Topic { // Topic is a named parameter
get
set
}

public string Url { get }
}

defines an attribute class named HelpAttribute that has one positional parameter (string url) and one named parameter (string Topic). Although it is non-static and public, the Url property does not define a named parameter because it is not read-write.

The example

[Help('https://www.microsoft.com//Class1.htm')]
class Class1

[Help('https://www.microsoft.com//Misc.htm', Topic ='Class2')]
class Class2

shows several uses of the attribute.

Attribute parameter types

The types of positional and named parameters for an attribute class are limited to the attribute parameter types, which are:

The types bool, byte, char, double, float, int, long, short, string.

The type object.

The type System.Type.

An enum type provided it has public accessibility and the types in which it is nested (if any) also have public accessibility.

Attribute specification

Attribute specification is the application of a previously defined attribute to a declaration. An attribute is a piece of additional declarative information that is specified for a declaration. Attributes can be specified at global scope (to specify attributes on the containing assembly or module) and for type-declarations (9.5), class-member-declarations (10.2), interface-member-declarations (13.2), enum-member-declarations (14.3), accessor-declarations for properties (10.6.2), event-accessor-declarations (10.7.1), and formal-parameter-lists (10.5.1).



Attributes are specified in attribute sections. An attribute section consists of a pair of square brackets, which surround a comma-separated list of one or more attributes. The order in which attributes are specified in such a list, and the order in which sections appear, is not significant. For instance, the attribute specifications [A][B], [B][A], [A, B], and [B, A] are equivalent.

attributes:
attribute-sections

attribute-sections:
attribute-section
attribute-sections attribute-section

attribute-section:
[ attribute-target-specifieropt attribute-list ]
[
attribute-target-specifieropt attribute-list , ]

attribute-target-specifier:
attribute-target
:

attribute-target:
assembly
field
event
method
module
param
property
return
type

attribute-list:
attribute
attribute-list
, attribute

attribute:
attribute-name attribute-argumentsopt

attribute-name:
type-name

attribute-arguments:
( positional-argument-listopt )
(
positional-argument-list , named-argument-list )
(
named-argument-list )

positional-argument-list:
positional-argument
positional-argument-list
, positional-argument

positional-argument:
attribute-argument-expression

named-argument-list:
named-argument
named-argument-list
, named-argument

named-argument:
identifier
= attribute-argument-expression

attribute-argument-expression:
expression

An attribute consists of an attribute-name and an optional list of positional and named arguments. The positional arguments (if any) precede the named arguments. A positional argument consists of an attribute-argument-expression; a named argument consists of a name, followed by an equal sign, followed by an attribute-argument-expression. The order of named arguments is not significant.

The attribute-name identifies either a reserved attribute or an attribute class. If the form of attribute-name is type-name then this name must refer to an attribute class. Otherwise, a compile-time error occurs. The example

class Class1

[Class1] class Class2 // Error

is in error because it attempts to use Class1, which is not an attribute class, as an attribute class.

Certain contexts permit the specification of an attribute on more than one target. A program can explicitly specify the target by including an attribute-target-specifier. In all but one of these contexts, a reasonable default can be employed. Thus, attribute-target-specifiers can typically be omitted. The potentially ambiguous contexts are resolved as follows:

An attribute specified at global scope can apply either to the target assembly or the target module. No default exists for this context, so an attribute-target-specifier is always required in this context. The presence of the assembly attribute-target-specifier indicates that the attribute applies to the target assembly; the presence of the module attribute-target-specifier indicates that the attribute applies to the target module.

An attribute specified on a delegate declaration can apply either to the delegate or to its return value. In the absence of an attribute-target-specifier, such an attribute applies to the delegate. The presence of the type attribute-target-specifier indicates that the attribute applies to the delegate; the presence of the return attribute-target-specifier indicates that the attribute applies to the return value.

An attribute specified on a method declaration can apply either to the method or to its return value. In the absence of an attribute-target-specifier, such an attribute applies to the method. The presence of the method attribute-target-specifier indicates that the attribute applies to the method; the presence of the return attribute-target-specifier indicates that the attribute applies to the return value.

An attribute specified on an operator declaration can apply either to the operator or to its return value. In the absence of an attribute-target-specifier, such an attribute applies to the operator. The presence of the type attribute-target-specifier indicates that the attribute applies to the operator; the presence of the return attribute-target-specifier indicates that the attribute applies to the return value.

An attribute specified on an event declaration that omits event accessors can apply to the event, to the associated field (if the event is non-abstract), or to the associated add and remove accessors. In the absence of an attribute-target-specifier, such an attribute applies to the event. The presence of the event attribute-target-specifier indicates that the attribute applies to the event; the presence of the field attribute-target-specifier indicates that the attribute applies to the field; and the presence of the method attribute-target-specifier indicates that the attribute applies to the associated add and remove accessors.

An attribute specified on a get accessor declaration for a property can apply either to the accessor or to its return value. In the absence of an attribute-target-specifier, such an attribute applies to the accessor. The presence of the method attribute-target-specifier indicates that the attribute applies to the accessor; the presence of the return attribute-target-specifier indicates that the attribute applies to the return value.

An attribute specified on a set accessor for a property can apply either to the accessor or to its implicit parameter. In the absence of an attribute-target-specifier, such an attribute applies to the accessor. The presence of the method attribute-target-specifier indicates that the attribute applies to the accessor; the presence of the param attribute-target-specifier indicates that the attribute applies to the parameter.

An attribute specified on an add or remove accessor for an event can apply either to the accessor or to its lone parameter. In the absence of an attribute-target-specifier, such an attribute applies to the accessor. The presence of the method attribute-target-specifier indicates that the attribute applies to the accessor; the presence of the param attribute-target-specifier indicates that the attribute applies to the parameter.

In other contexts, inclusion of an attribute-target-specifier is permitted but unnecessary. For instance, a class declaration may either include or omit the type attribute-target-specifier:

[type: Author('Brian Kernighan')]
class Class1

[Author('Dennis Ritchie')]
class Class2

It is an error to specify an invalid attribute-target-specifier. For instance, the param attribute-target-specifier cannot be used on a class declaration:

[param: Author('Brian Kernighan')]
class Class1

An implementation may accept additional attribute target specifiers with implementation-defined semantics. However, an implementation that does not recognize such a target shall issue a warning.

By convention, attribute classes are named with a suffix of Attribute. An attribute-name of the form type-name may either include or omit this suffix. An exact match between the attribute-name and the name of the attribute class is preferred. The example

[AttributeUsage(AttributeTargets.All)]
public class X: Attribute

[AttributeUsage(AttributeTargets.All)]
public class XAttribute: Attribute

[X] // refers to X
class Class1

[XAttribute] // refers to XAttribute
class Class2

shows two attribute classes named X and XAttribute. The attribute [X] refers to the class named X, and the attribute [XAttribute] refers to the attribute class named [XAttribute]. If the declaration for class X is removed, then both attributes refer to the attribute class named XAttribute:



[AttributeUsage(AttributeTargets.All)]
public class XAttribute: Attribute

[X] // refers to XAttribute
class Class1

[XAttribute] // refers to XAttribute
class Class2

It is an error to use a single-use attribute class more than once on the same entity. The example

[AttributeUsage(AttributeTargets.Class)]
public class HelpStringAttribute: Attribute

public string Value { get }
}

[HelpString('Description of Class1')]
[HelpString('Another description of Class1')]
public class Class1

is in error because it attempts to use HelpString, which is a single-use attribute class, more than once on the declaration of Class1.

An expression E is an attribute-argument-expression if all of the following statements are true:

The type of E is an attribute parameter type (17.1.3).

At compile-time, the value of E can be resolved to one of the following:

A constant-expression (7.15).

A typeof-expression (7.5.11).

An array-creation-expression (7.5.10.2) of the form new T[] , where T is an attribute parameter type and each E is an attribute-argument-expression.

Attribute instances

An attribute instance is an instance that represents an attribute at run-time. An attribute is defined with an attribute class, positional arguments, and named arguments. An attribute instance is an instance of the attribute class that is initialized with the positional and named arguments.

Retrieval of an attribute instance involves both compile-time and run-time processing, as described in the following sections.

Compilation of an attribute

The compilation of an attribute with attribute class T, positional-argument-list P and named-argument-list N, consists of the following steps:

Follow the compile-time processing steps for compiling an object-creation-expression of the form new T(P). These steps either result in a compile-time error, or determine a constructor on T that can be invoked at run-time. Call this instance constructor C.

If C does not have public accessibility, then a compile-time error occurs.

For each named-argument Arg in N:

Let Name be the identifier of the named-argument Arg.

Name must identify a non-static read-write public field or property on T. If T has no such field or property, then a compile-time error occurs.

Keep the following information for run-time instantiation of the attribute: the attribute class T, the instance constructor C on T, the positional-argument-list P and the named-argument-list N.

Run-time retrieval of an attribute instance

Compilation of an attribute yields an attribute class T, an instance constructor C on T, a positional-argument-list P and a named-argument-list N. Given this information, an attribute instance can be retrieved at run-time using the following steps:

Follow the run-time processing steps for executing an object-creation-expression of the form new T(P), using the instance constructor C as determined at compile-time. These steps either result in an exception, or produce an instance of T. Call this instance O.

For each named-argument Arg in N, in order:

Let Name be the identifier of the named-argument Arg. If Name does not identify a non-static public read-write field or property on O, then an exception is thrown.

Let Value be the result of evaluating the attribute-argument-expression of Arg.

If Name identifies a field on O, then set this field to the value Value.

Otherwise, Name identifies a property on O. 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.

Reserved attributes

A small number of attributes affect the language in some way. These attributes include:

System.AttributeUsageAttribute (17.4.1), which is used to describe the ways in which an attribute class can be used.

System.ConditionalAttribute (17.4.2), which is used to define conditional methods.



System.ObsoleteAttribute (17.4.3), which is used to mark a member as obsolete.

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: Attribute
{
public AttributeUsageAttribute(AttributeTargets validOn)

public virtual bool AllowMultiple { get set }

public virtual bool Inherited { get set }

public virtual AttributeTargets ValidOn { get }
}

public enum AttributeTargets


The Conditional attribute

The Conditional attribute enables the definition of conditional methods. The Conditional attribute indicates a condition by testing a conditional compilation symbol. 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 call is included; otherwise, the call is omitted.

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class ConditionalAttribute: Attribute
{
public ConditionalAttribute(string conditionalSymbol)

public string ConditionalSymbol { get }
}

A conditional method is subject to the following restrictions:

The conditional method must be a method in a class-declaration.

The conditional method must not be an override method.

The conditional method must 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, however. 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.

In addition, a compile-time error occurs if a conditional method is used in a delegate-creation-expression. The example

#define DEBUG

using System.Diagnostics;

class Class1

}

class Class2

}

declares Class1.M as a conditional method. Class2's Test method calls this method. Since the conditional compilation 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 conditional compilation symbols at the point of the call. In the example

// Begin class1.cs
using System.Diagnostics;

class Class1

}
// End class1.cs

// Begin class2.cs
#define DEBUG

using System.Diagnostics;

class Class2

}
// End class2.cs

// Begin class3.cs
#undef DEBUG

class Class3

}
// End class3.cs

the classes Class2 and Class3 each contain calls to the conditional method Class1.F, which is conditional based on whether DEBUG is defined. Since this symbol is defined in the context of Class2 but not Class3, the call to F in Class2 is included, while the call to F in Class3 is omitted.

The Obsolete attribute

The Obsolete attribute is used to mark program elements that should no longer be used.

[AttributeUsage(AttributeTargets.All)]
public class ObsoleteAttribute: Attribute
{

public ObsoleteAttribute(string message)

public ObsoleteAttribute(string message, bool error)

public string Message { get }

public bool IsError { get }
}

If a program uses a program element that is decorated with the Obsolete attribute, then the compiler shall issue a warning or error in order to alert the developer, so the offending code can be fixed. Specifically, the compiler shall issue a warning if no error parameter is provided, or if the error parameter is provided and has the value false. The compiler shall issue an error if the error parameter is specified and has the value true.

In the example

[Obsolete('This class is obsolete; use class B instead')]
class A
{
public void F()
}

class B
{
public void F()
}

class Test

}

the class A is decorated with the Obsolete attribute. The use of A in Main results in a warning that includes the specified message, "This class is obsolete; use class B instead."





Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 919
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved