AtributosAttributes

Grande parte da linguagem C# permite que o programador especifique informações declarativas sobre as entidades definidas no programa.Much of the C# language enables the programmer to specify declarative information about the entities defined in the program. Por exemplo, a acessibilidade de um método em uma classe é especificada decorando-o com o method_modifier s public , protected , internal , e private .For example, the accessibility of a method in a class is specified by decorating it with the method_modifier s public, protected, internal, and private.

O C# permite que os programadores ininventam novos tipos de informações declarativas, chamados atributos.C# enables programmers to invent new kinds of declarative information, called attributes. Os programadores podem anexar atributos a várias entidades de programa e recuperar informações de atributo em um ambiente de tempo de execução.Programmers can then attach attributes to various program entities, and retrieve attribute information in a run-time environment. Por exemplo, uma estrutura pode definir um HelpAttribute atributo que pode ser colocado em determinados elementos do programa (como classes e métodos) para fornecer um mapeamento desses elementos de programa para sua documentação.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 their documentation.

Os atributos são definidos por meio da declaração de classes de atributo (classes de atributo), que podem ter parâmetros posicionais e nomeados (parâmetros posicionais e nomeados).Attributes are defined through the declaration of attribute classes (Attribute classes), which may have positional and named parameters (Positional and named parameters). Os atributos são anexados a entidades em um programa em C# usando especificações de atributo (especificação de atributo) e podem ser recuperados em tempo de execução como instâncias de atributo (instâncias de atributo).Attributes are attached to entities in a C# program using attribute specifications (Attribute specification), and can be retrieved at run-time as attribute instances (Attribute instances).

Classes de atributosAttribute classes

Uma classe que deriva da classe abstrata System.Attribute , direta ou indiretamente, é uma classe de atributo* _.A class that derives from the abstract class System.Attribute, whether directly or indirectly, is an *attribute class _. A declaração de uma classe de atributo define um novo tipo de _ Attribute* que pode ser colocado em uma declaração.The declaration of an attribute class defines a new kind of _ attribute* that can be placed on a declaration. Por convenção, as classes de atributo são nomeadas com um sufixo de Attribute .By convention, attribute classes are named with a suffix of Attribute. O uso de um atributo pode incluir ou omitir esse sufixo.Uses of an attribute may either include or omit this suffix.

Uso de atributoAttribute usage

O atributo AttributeUsage (o atributo AttributeUsage) é usado para descrever como uma classe de atributo pode ser usada.The attribute AttributeUsage (The AttributeUsage attribute) is used to describe how an attribute class can be used.

AttributeUsage tem um parâmetro posicional (parâmetros posicionais e nomeados) que permite que uma classe de atributo especifique os tipos de declarações nas quais ele pode ser usado.AttributeUsage has a positional parameter (Positional and named parameters) that enables an attribute class to specify the kinds of declarations on which it can be used. O exemploThe example

using System;

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

define uma classe de atributo chamada SimpleAttribute que pode ser colocada somente em class_declaration s e interface_declaration s.defines an attribute class named SimpleAttribute that can be placed on class_declaration s and interface_declaration s only. O exemploThe example

[Simple] class Class1 {...}

[Simple] interface Interface1 {...}

mostra vários usos do Simple atributo.shows several uses of the Simple attribute. Embora esse atributo seja definido com o nome SimpleAttribute , quando esse atributo é usado, o Attribute sufixo pode ser omitido, resultando no nome curto Simple .Although this attribute is defined with the name SimpleAttribute, when this attribute is used, the Attribute suffix may be omitted, resulting in the short name Simple. Portanto, o exemplo acima é semanticamente equivalente ao seguinte:Thus, the example above is semantically equivalent to the following:

[SimpleAttribute] class Class1 {...}

[SimpleAttribute] interface Interface1 {...}

AttributeUsage tem um parâmetro nomeado (parâmetros posicionais e nomeados) chamado AllowMultiple , que indica se o atributo pode ser especificado mais de uma vez para uma determinada entidade.AttributeUsage has a named parameter (Positional and named parameters) called AllowMultiple, which indicates whether the attribute can be specified more than once for a given entity. Se AllowMultiple para uma classe de atributo for true, essa classe de atributo será uma classe de atributo * multi-uso* e poderá ser especificada mais de uma vez em uma entidade.If AllowMultiple for an attribute class is true, then that attribute class is a *multi-use attribute class _, and can be specified more than once on an entity. Se AllowMultiple for uma classe de atributo for false ou não for especificada, essa classe de atributo será uma classe de atributo _ de uso único* * e poderá ser especificada no máximo uma vez em uma entidade.If AllowMultiple for an attribute class is false or it is unspecified, then that attribute class is a _*single-use attribute class**, and can be specified at most once on an entity.

O exemploThe example

using System;

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class AuthorAttribute: Attribute
{
    private string name;

    public AuthorAttribute(string name) {
        this.name = name;
    }

    public string Name {
        get { return name; }
    }
}

define uma classe de atributo de uso múltiplo chamada AuthorAttribute .defines a multi-use attribute class named AuthorAttribute. O exemploThe example

[Author("Brian Kernighan"), Author("Dennis Ritchie")] 
class Class1
{
    ...
}

mostra uma declaração de classe com dois usos do Author atributo.shows a class declaration with two uses of the Author attribute.

AttributeUsage tem outro parâmetro nomeado chamado Inherited , que indica se o atributo, quando especificado em uma classe base, também é herdado por classes que derivam dessa classe base.AttributeUsage has another named parameter called Inherited, which indicates whether the attribute, when specified on a base class, is also inherited by classes that derive from that base class. Se Inherited para uma classe de atributo for true, esse atributo será herdado.If Inherited for an attribute class is true, then that attribute is inherited. Se Inherited for uma classe de atributo for false, esse atributo não será herdado.If Inherited for an attribute class is false then that attribute is not inherited. Se não for especificado, seu valor padrão será true.If it is unspecified, its default value is true.

Uma classe X de atributo que não tem um AttributeUsage atributo anexado a ela, como emAn attribute class X not having an AttributeUsage attribute attached to it, as in

using System;

class X: Attribute {...}

é equivalente ao seguinte:is equivalent to the following:

using System;

[AttributeUsage(
    AttributeTargets.All,
    AllowMultiple = false,
    Inherited = true)
]
class X: Attribute {...}

Parâmetros posicionais e nomeadosPositional and named parameters

As classes de atributo podem ter *parâmetros posicionais _ e _ parâmetros nomeados *.Attribute classes can have positional parameters _ and _named parameters**. Cada Construtor de instância pública para uma classe de atributo define uma sequência válida de parâmetros posicionais para essa classe de atributo.Each public instance constructor for an attribute class defines a valid sequence of positional parameters for that attribute class. Cada campo de leitura/gravação público não estático e propriedade para uma classe de atributo define um parâmetro nomeado para a classe de atributo.Each non-static public read-write field and property for an attribute class defines a named parameter for the attribute class.

O exemploThe example

using System;

[AttributeUsage(AttributeTargets.Class)]
public class HelpAttribute: Attribute
{
    public HelpAttribute(string url) {        // Positional parameter
        ...
    }

    public string Topic {                     // Named parameter
        get {...}
        set {...}
    }

    public string Url {
        get {...}
    }
}

define uma classe de atributo chamada HelpAttribute que tem um parâmetro posicional, url e um parâmetro nomeado, Topic .defines an attribute class named HelpAttribute that has one positional parameter, url, and one named parameter, Topic. Embora seja não estático e público, a propriedade não Url define um parâmetro nomeado, pois não é de leitura/gravação.Although it is non-static and public, the property Url does not define a named parameter, since it is not read-write.

Essa classe de atributo pode ser usada da seguinte maneira:This attribute class might be used as follows:

[Help("http://www.mycompany.com/.../Class1.htm")]
class Class1
{
    ...
}

[Help("http://www.mycompany.com/.../Misc.htm", Topic = "Class2")]
class Class2
{
    ...
}

Tipos de parâmetro de atributoAttribute parameter types

Os tipos de parâmetros posicionais e nomeados para uma classe de atributo são limitados aos tipos de parâmetro de atributo, que são:The types of positional and named parameters for an attribute class are limited to the attribute parameter types, which are:

  • Um dos seguintes tipos:,,,,,, bool byte char double float int long , sbyte ,,,,, short string uint ulong ushort .One of the following types: bool, byte, char, double, float, int, long, sbyte, short, string, uint, ulong, ushort.
  • O tipo object.The type object.
  • O tipo System.Type.The type System.Type.
  • Um tipo de enumeração, desde que ele tenha acessibilidade pública e os tipos em que ele está aninhado (se houver) também têm acessibilidade pública (especificação de atributo).An enum type, provided it has public accessibility and the types in which it is nested (if any) also have public accessibility (Attribute specification).
  • Matrizes unidimensionais dos tipos acima.Single-dimensional arrays of the above types.
  • Um argumento de construtor ou campo público que não tem um desses tipos não pode ser usado como um parâmetro posicional ou nomeado em uma especificação de atributo.A constructor argument or public field which does not have one of these types, cannot be used as a positional or named parameter in an attribute specification.

Especificação de atributoAttribute specification

*A especificação de atributo _ é o aplicativo de um atributo previamente definido para uma declaração.*Attribute specification _ is the application of a previously defined attribute to a declaration. Um atributo é uma parte das informações declarativas adicionais que são especificadas para uma declaração.An attribute is a piece of additional declarative information that is specified for a declaration. Os atributos podem ser especificados no escopo global (para especificar atributos no assembly ou módulo que contém) e para _type_declaration * s (declarações de tipo), class_member_declaration s (restrições de parâmetro de tipo), interface_member_declaration s (membros da interface), struct_member_declaration s (membros de struct), enum_member_declaration s (membros de enumeração), Accessor_declarations (acessadores), event_accessor_declarations (eventos de Campo) e formal_parameter_list s (parâmetros de método).Attributes can be specified at global scope (to specify attributes on the containing assembly or module) and for _type_declaration*s (Type declarations), class_member_declaration s (Type parameter constraints), interface_member_declaration s (Interface members), struct_member_declaration s (Struct members), enum_member_declaration s (Enum members), accessor_declarations (Accessors), event_accessor_declarations (Field-like events), and formal_parameter_list s (Method parameters).

Os atributos são especificados em seções de atributo.Attributes are specified in attribute sections. Uma seção de atributo consiste em um par de colchetes, que envolve uma lista separada por vírgulas de um ou mais atributos.An attribute section consists of a pair of square brackets, which surround a comma-separated list of one or more attributes. A ordem na qual os atributos são especificados em uma lista como essa, e a ordem em que as seções anexadas à mesma entidade do programa são organizadas, não é significativa.The order in which attributes are specified in such a list, and the order in which sections attached to the same program entity are arranged, is not significant. Por exemplo, as especificações de atributo [A][B] , [B][A] , [A,B] e [B,A] são equivalentes.For instance, the attribute specifications [A][B], [B][A], [A,B], and [B,A] are equivalent.

global_attributes
    : global_attribute_section+
    ;

global_attribute_section
    : '[' global_attribute_target_specifier attribute_list ']'
    | '[' global_attribute_target_specifier attribute_list ',' ']'
    ;

global_attribute_target_specifier
    : global_attribute_target ':'
    ;

global_attribute_target
    : 'assembly'
    | 'module'
    ;

attributes
    : attribute_section+
    ;

attribute_section
    : '[' attribute_target_specifier? attribute_list ']'
    | '[' attribute_target_specifier? attribute_list ',' ']'
    ;

attribute_target_specifier
    : attribute_target ':'
    ;

attribute_target
    : 'field'
    | 'event'
    | 'method'
    | 'param'
    | 'property'
    | 'return'
    | 'type'
    ;

attribute_list
    : attribute (',' attribute)*
    ;

attribute
    : attribute_name attribute_arguments?
    ;

attribute_name
    : type_name
    ;

attribute_arguments
    : '(' positional_argument_list? ')'
    | '(' positional_argument_list ',' named_argument_list ')'
    | '(' named_argument_list ')'
    ;

positional_argument_list
    : positional_argument (',' positional_argument)*
    ;

positional_argument
    : attribute_argument_expression
    ;

named_argument_list
    : named_argument (','  named_argument)*
    ;

named_argument
    : identifier '=' attribute_argument_expression
    ;

attribute_argument_expression
    : expression
    ;

Um atributo consiste em um ATTRIBUTE_NAME e uma lista opcional de argumentos posicionais e nomeados.An attribute consists of an attribute_name and an optional list of positional and named arguments. Os argumentos posicionais (se houver) precedem os argumentos nomeados.The positional arguments (if any) precede the named arguments. Um argumento posicional consiste em um attribute_argument_expression; um argumento nomeado consiste em um nome, seguido por um sinal de igual, seguido por um attribute_argument_expression, que, juntos, são restritos pelas mesmas regras que a atribuição simples.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, which, together, are constrained by the same rules as simple assignment. A ordem dos argumentos nomeados não é significativa.The order of named arguments is not significant.

O ATTRIBUTE_NAME identifica uma classe de atributo.The attribute_name identifies an attribute class. Se a forma de ATTRIBUTE_NAME for type_name , esse nome deverá se referir a uma classe de atributo.If the form of attribute_name is type_name then this name must refer to an attribute class. Caso contrário, ocorrerá um erro de tempo de compilação.Otherwise, a compile-time error occurs. O exemploThe example

class Class1 {}

[Class1] class Class2 {}    // Error

resulta em um erro de tempo de compilação porque ele tenta usar Class1 como uma classe de atributo quando Class1 não é uma classe de atributo.results in a compile-time error because it attempts to use Class1 as an attribute class when Class1 is not an attribute class.

Determinados contextos permitem a especificação de um atributo em mais de um destino.Certain contexts permit the specification of an attribute on more than one target. Um programa pode especificar explicitamente o destino incluindo um attribute_target_specifier.A program can explicitly specify the target by including an attribute_target_specifier. Quando um atributo é colocado no nível global, um global_attribute_target_specifier é necessário.When an attribute is placed at the global level, a global_attribute_target_specifier is required. Em todos os outros locais, um padrão razoável é aplicado, mas um attribute_target_specifier pode ser usado para afirmar ou substituir o padrão em determinados casos ambíguos (ou apenas para afirmar o padrão em casos não ambíguos).In all other locations, a reasonable default is applied, but an attribute_target_specifier can be used to affirm or override the default in certain ambiguous cases (or to just affirm the default in non-ambiguous cases). Portanto, normalmente, attribute_target_specifier s pode ser omitido, exceto no nível global.Thus, typically, attribute_target_specifier s can be omitted except at the global level. Os contextos potencialmente ambíguos são resolvidos da seguinte maneira:The potentially ambiguous contexts are resolved as follows:

  • Um atributo especificado em escopo global pode ser aplicado ao assembly de destino ou ao módulo de destino.An attribute specified at global scope can apply either to the target assembly or the target module. Não existe nenhum padrão para esse contexto, portanto, um attribute_target_specifier sempre é necessário neste contexto.No default exists for this context, so an attribute_target_specifier is always required in this context. A presença do assembly attribute_target_specifier indica que o atributo se aplica ao assembly de destino; a presença do module attribute_target_specifier indica que o atributo se aplica ao módulo de destino.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.
  • Um atributo especificado em uma declaração delegate pode ser aplicado ao delegado que está sendo declarado ou ao valor de retorno.An attribute specified on a delegate declaration can apply either to the delegate being declared or to its return value. Na ausência de um attribute_target_specifier, o atributo se aplica ao delegado.In the absence of an attribute_target_specifier, the attribute applies to the delegate. A presença do type attribute_target_specifier indica que o atributo se aplica ao delegado; a presença do return attribute_target_specifier indica que o atributo se aplica ao valor de retorno.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.
  • Um atributo especificado em uma declaração de método pode ser aplicado ao método que está sendo declarado ou ao valor de retorno.An attribute specified on a method declaration can apply either to the method being declared or to its return value. Na ausência de um attribute_target_specifier, o atributo se aplica ao método.In the absence of an attribute_target_specifier, the attribute applies to the method. A presença do method attribute_target_specifier indica que o atributo se aplica ao método; a presença do return attribute_target_specifier indica que o atributo se aplica ao valor de retorno.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.
  • Um atributo especificado em uma declaração de operador pode ser aplicado ao operador que está sendo declarado ou ao valor de retorno.An attribute specified on an operator declaration can apply either to the operator being declared or to its return value. Na ausência de um attribute_target_specifier, o atributo se aplica ao operador.In the absence of an attribute_target_specifier, the attribute applies to the operator. A presença do method attribute_target_specifier indica que o atributo se aplica ao operador; a presença do return attribute_target_specifier indica que o atributo se aplica ao valor de retorno.The presence of the method 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.
  • Um atributo especificado em uma declaração de evento que omite acessadores de eventos pode se aplicar ao evento que está sendo declarado, ao campo associado (se o evento não for abstrato) ou aos métodos adicionar e remover associados.An attribute specified on an event declaration that omits event accessors can apply to the event being declared, to the associated field (if the event is not abstract), or to the associated add and remove methods. Na ausência de um attribute_target_specifier, o atributo se aplica ao evento.In the absence of an attribute_target_specifier, the attribute applies to the event. A presença do event attribute_target_specifier indica que o atributo se aplica ao evento; a presença do field attribute_target_specifier indica que o atributo se aplica ao campo; e a presença do method attribute_target_specifier indica que o atributo se aplica aos métodos.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 methods.
  • Um atributo especificado em uma Declaração Get do acessador para uma propriedade ou declaração do indexador pode se aplicar ao método associado ou ao valor de retorno.An attribute specified on a get accessor declaration for a property or indexer declaration can apply either to the associated method or to its return value. Na ausência de um attribute_target_specifier, o atributo se aplica ao método.In the absence of an attribute_target_specifier, the attribute applies to the method. A presença do method attribute_target_specifier indica que o atributo se aplica ao método; a presença do return attribute_target_specifier indica que o atributo se aplica ao valor de retorno.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.
  • Um atributo especificado em um acessador set para uma declaração de propriedade ou de indexador pode se aplicar ao método associado ou ao seu parâmetro implícito solitário.An attribute specified on a set accessor for a property or indexer declaration can apply either to the associated method or to its lone implicit parameter. Na ausência de um attribute_target_specifier, o atributo se aplica ao método.In the absence of an attribute_target_specifier, the attribute applies to the method. A presença do method attribute_target_specifier indica que o atributo se aplica ao método; a presença do param attribute_target_specifier indica que o atributo se aplica ao parâmetro; a presença do return attribute_target_specifier indica que o atributo se aplica ao valor de retorno.The presence of the method attribute_target_specifier indicates that the attribute applies to the method; the presence of the param attribute_target_specifier indicates that the attribute applies to the parameter; the presence of the return attribute_target_specifier indicates that the attribute applies to the return value.
  • Um atributo especificado em uma declaração de acessador Add ou remove para uma declaração de evento pode ser aplicado ao método associado ou ao seu parâmetro solitário.An attribute specified on an add or remove accessor declaration for an event declaration can apply either to the associated method or to its lone parameter. Na ausência de um attribute_target_specifier, o atributo se aplica ao método.In the absence of an attribute_target_specifier, the attribute applies to the method. A presença do method attribute_target_specifier indica que o atributo se aplica ao método; a presença do param attribute_target_specifier indica que o atributo se aplica ao parâmetro; a presença do return attribute_target_specifier indica que o atributo se aplica ao valor de retorno.The presence of the method attribute_target_specifier indicates that the attribute applies to the method; the presence of the param attribute_target_specifier indicates that the attribute applies to the parameter; the presence of the return attribute_target_specifier indicates that the attribute applies to the return value.

Em outros contextos, a inclusão de um attribute_target_specifier é permitida, mas desnecessária.In other contexts, inclusion of an attribute_target_specifier is permitted but unnecessary. Por exemplo, uma declaração de classe pode incluir ou omitir o especificador type :For instance, a class declaration may either include or omit the specifier type:

[type: Author("Brian Kernighan")]
class Class1 {}

[Author("Dennis Ritchie")]
class Class2 {}

É um erro especificar um attribute_target_specifier inválido.It is an error to specify an invalid attribute_target_specifier. Por exemplo, o especificador param não pode ser usado em uma declaração de classe:For instance, the specifier param cannot be used on a class declaration:

[param: Author("Brian Kernighan")]        // Error
class Class1 {}

Por convenção, as classes de atributo são nomeadas com um sufixo de Attribute .By convention, attribute classes are named with a suffix of Attribute. Uma ATTRIBUTE_NAME do formulário type_name pode incluir ou omitir esse sufixo.An attribute_name of the form type_name may either include or omit this suffix. Se uma classe de atributo for encontrada com e sem esse sufixo, uma ambiguidade estará presente e ocorrerá um erro de tempo de compilação.If an attribute class is found both with and without this suffix, an ambiguity is present, and a compile-time error results. Se o ATTRIBUTE_NAME for escrito de forma que seu identificador mais à direita seja um identificador textual (identificadores), somente um atributo sem um sufixo será correspondido, permitindo assim que essa ambiguidade seja resolvida.If the attribute_name is spelled such that its right-most identifier is a verbatim identifier (Identifiers), then only an attribute without a suffix is matched, thus enabling such an ambiguity to be resolved. O exemploThe example

using System;

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

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

[X]                     // Error: ambiguity
class Class1 {}

[XAttribute]            // Refers to XAttribute
class Class2 {}

[@X]                    // Refers to X
class Class3 {}

[@XAttribute]           // Refers to XAttribute
class Class4 {}

mostra duas classes de atributo chamadas X e XAttribute .shows two attribute classes named X and XAttribute. O atributo [X] é ambíguo, pois ele pode se referir a um X ou XAttribute .The attribute [X] is ambiguous, since it could refer to either X or XAttribute. O uso de um identificador textual permite que a intenção exata seja especificada nesses casos raros.Using a verbatim identifier allows the exact intent to be specified in such rare cases. O atributo [XAttribute] não é ambíguo (embora seja uma classe de atributo chamada XAttributeAttribute !).The attribute [XAttribute] is not ambiguous (although it would be if there was an attribute class named XAttributeAttribute!). Se a declaração para a classe X for removida, ambos os atributos referem-se à classe de atributo denominada XAttribute , da seguinte maneira:If the declaration for class X is removed, then both attributes refer to the attribute class named XAttribute, as follows:

using System;

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

[X]                     // Refers to XAttribute
class Class1 {}

[XAttribute]            // Refers to XAttribute
class Class2 {}

[@X]                    // Error: no attribute named "X"
class Class3 {}

É um erro de tempo de compilação para usar uma classe de atributo de uso único mais de uma vez na mesma entidade.It is a compile-time error to use a single-use attribute class more than once on the same entity. O exemploThe example

using System;

[AttributeUsage(AttributeTargets.Class)]
public class HelpStringAttribute: Attribute
{
    string value;

    public HelpStringAttribute(string value) {
        this.value = value;
    }

    public string Value {
        get {...}
    }
}

[HelpString("Description of Class1")]
[HelpString("Another description of Class1")]
public class Class1 {}

resulta em um erro de tempo de compilação porque ele tenta usar HelpString , que é uma classe de atributo de uso único, mais de uma vez na declaração de Class1 .results in a compile-time error because it attempts to use HelpString, which is a single-use attribute class, more than once on the declaration of Class1.

Uma expressão E é uma attribute_argument_expression se todas as seguintes instruções forem verdadeiras:An expression E is an attribute_argument_expression if all of the following statements are true:

  • O tipo de E é um tipo de parâmetro de atributo (tipos de parâmetro de atributo).The type of E is an attribute parameter type (Attribute parameter types).
  • Em tempo de compilação, o valor de E pode ser resolvido para um dos seguintes:At compile-time, the value of E can be resolved to one of the following:
    • Um valor constante.A constant value.
    • Um objeto System.Type.A System.Type object.
    • Uma matriz unidimensional de attribute_argument_expression s.A one-dimensional array of attribute_argument_expression s.

Por exemplo:For example:

using System;

[AttributeUsage(AttributeTargets.Class)]
public class TestAttribute: Attribute
{
    public int P1 {
        get {...}
        set {...}
    }

    public Type P2 {
        get {...}
        set {...}
    }

    public object P3 {
        get {...}
        set {...}
    }
}

[Test(P1 = 1234, P3 = new int[] {1, 3, 5}, P2 = typeof(float))]
class MyClass {}

Um typeof_expression (o operador typeof) usado como uma expressão de argumento de atributo pode referenciar um tipo não genérico, um tipo construído fechado ou um tipo genérico não associado, mas não pode fazer referência a um tipo aberto.A typeof_expression (The typeof operator) used as an attribute argument expression can reference a non-generic type, a closed constructed type, or an unbound generic type, but it cannot reference an open type. Isso é para garantir que a expressão possa ser resolvida em tempo de compilação.This is to ensure that the expression can be resolved at compile-time.

class A: Attribute
{
    public A(Type t) {...}
}

class G<T>
{
    [A(typeof(T))] T t;                  // Error, open type in attribute
}

class X
{
    [A(typeof(List<int>))] int x;        // Ok, closed constructed type
    [A(typeof(List<>))] int y;           // Ok, unbound generic type
}

Instâncias de atributosAttribute instances

Uma instância de atributo é uma instância que representa um atributo em tempo de execução.An attribute instance is an instance that represents an attribute at run-time. Um atributo é definido com uma classe de atributo, argumentos posicionais e argumentos nomeados.An attribute is defined with an attribute class, positional arguments, and named arguments. Uma instância de atributo é uma instância da classe de atributo que é inicializada com os argumentos posicionais e nomeados.An attribute instance is an instance of the attribute class that is initialized with the positional and named arguments.

A recuperação de uma instância de atributo envolve o processamento em tempo de compilação e em tempo de execução, conforme descrito nas seções a seguir.Retrieval of an attribute instance involves both compile-time and run-time processing, as described in the following sections.

Compilação de um atributoCompilation of an attribute

A compilação de um atributo com classe de atributo T , positional_argument_list P e named_argument_list N , consiste nas seguintes etapas:The compilation of an attribute with attribute class T, positional_argument_list P and named_argument_list N, consists of the following steps:

  • Siga as etapas de processamento em tempo de compilação para compilar uma object_creation_expression do formulário new T(P) .Follow the compile-time processing steps for compiling an object_creation_expression of the form new T(P). Essas etapas resultam em um erro de tempo de compilação ou determinam um construtor C de instância no T que pode ser invocado em tempo de execução.These steps either result in a compile-time error, or determine an instance constructor C on T that can be invoked at run-time.
  • Se C o não tiver uma acessibilidade pública, ocorrerá um erro de tempo de compilação.If C does not have public accessibility, then a compile-time error occurs.
  • Para cada named_argument Arg em N :For each named_argument Arg in N:
    • Deixe Name o identificador da named_argument Arg .Let Name be the identifier of the named_argument Arg.
    • Name deve identificar um campo ou propriedade pública de leitura/gravação não estática em T .Name must identify a non-static read-write public field or property on T. Se T não tiver tal campo ou propriedade, ocorrerá um erro de tempo de compilação.If T has no such field or property, then a compile-time error occurs.
  • Mantenha as seguintes informações para instanciação de tempo de execução do atributo: a classe de atributo T , o construtor de instância C em T , o positional_argument_list P e o named_argument_list N .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.

Recuperação de tempo de execução de uma instância de atributoRun-time retrieval of an attribute instance

A compilação de um atributo produz uma classe de atributo T , um construtor de instância C em T , um positional_argument_list P e um named_argument_list N .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. Dadas essas informações, uma instância de atributo pode ser recuperada em tempo de execução usando as seguintes etapas:Given this information, an attribute instance can be retrieved at run-time using the following steps:

  • Siga as etapas de processamento em tempo de execução para executar uma object_creation_expression do formulário new T(P) , usando o construtor de instância C como determinado em tempo de compilação.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. Essas etapas resultam em uma exceção ou produzem uma instância O do T .These steps either result in an exception, or produce an instance O of T.
  • Para cada named_argument Arg em N , em ordem:For each named_argument Arg in N, in order:
    • Deixe Name o identificador da named_argument Arg .Let Name be the identifier of the named_argument Arg. Se Name o não identificar um campo ou uma propriedade de leitura/gravação pública não estática em O , uma exceção será lançada.If Name does not identify a non-static public read-write field or property on O, then an exception is thrown.
    • Vamos Value ser o resultado da avaliação da attribute_argument_expression de Arg .Let Value be the result of evaluating the attribute_argument_expression of Arg.
    • Se Name o identificar um campo em O , defina esse campo como Value .If Name identifies a field on O, then set this field to Value.
    • Caso contrário, Name identifica uma propriedade em O .Otherwise, Name identifies a property on O. Defina esta propriedade como Value.Set this property to Value.
    • O resultado é O uma instância da classe de atributo T que foi inicializada com o positional_argument_list P e o named_argument_list N .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.

Atributos reservadosReserved attributes

Um pequeno número de atributos afeta o idioma de alguma forma.A small number of attributes affect the language in some way. Esses atributos incluem:These attributes include:

  • System.AttributeUsageAttribute (O atributo AttributeUsage), que é usado para descrever as maneiras em que uma classe de atributo pode ser usada.System.AttributeUsageAttribute (The AttributeUsage attribute), which is used to describe the ways in which an attribute class can be used.
  • System.Diagnostics.ConditionalAttribute (O atributo Conditional), que é usado para definir métodos condicionais.System.Diagnostics.ConditionalAttribute (The Conditional attribute), which is used to define conditional methods.
  • System.ObsoleteAttribute (O atributo obsoleto), que é usado para marcar um membro como obsoleto.System.ObsoleteAttribute (The Obsolete attribute), which is used to mark a member as obsolete.
  • System.Runtime.CompilerServices.CallerLineNumberAttribute``System.Runtime.CompilerServices.CallerFilePathAttributee System.Runtime.CompilerServices.CallerMemberNameAttribute (atributos deinformações do chamador), que são usados para fornecer informações sobre o contexto de chamada para parâmetros opcionais.System.Runtime.CompilerServices.CallerLineNumberAttribute, System.Runtime.CompilerServices.CallerFilePathAttribute and System.Runtime.CompilerServices.CallerMemberNameAttribute (Caller info attributes), which are used to supply information about the calling context to optional parameters.

O atributo AttributeUsageThe AttributeUsage attribute

O atributo AttributeUsage é usado para descrever a maneira como a classe de atributo pode ser usada.The attribute AttributeUsage is used to describe the manner in which the attribute class can be used.

Uma classe que é decorada com o AttributeUsage atributo deve derivar de System.Attribute , direta ou indiretamente.A class that is decorated with the AttributeUsage attribute must derive from System.Attribute, either directly or indirectly. Caso contrário, ocorrerá um erro de tempo de compilação.Otherwise, a compile-time error occurs.

namespace System
{
    [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
    {
        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,
        ReturnValue  = 0x2000,

        All = Assembly | Module | Class | Struct | Enum | Constructor | 
            Method | Property | Field | Event | Interface | Parameter | 
            Delegate | ReturnValue
    }
}

O atributo ConditionalThe Conditional attribute

O atributo Conditional habilita a definição de *métodos condicionais _ e _ classes de atributo condicional *.The attribute Conditional enables the definition of conditional methods _ and _conditional attribute classes**.

namespace System.Diagnostics
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
    public class ConditionalAttribute: Attribute
    {
        public ConditionalAttribute(string conditionString) {...}
        public string ConditionString { get {...} }
    }
}

Métodos condicionaisConditional methods

Um método decorado com o Conditional atributo é um método condicional.A method decorated with the Conditional attribute is a conditional method. O Conditional atributo indica uma condição testando um símbolo de compilação condicional.The Conditional attribute indicates a condition by testing a conditional compilation symbol. Chamadas para um método condicional são incluídas ou omitidas dependendo se esse símbolo é definido no ponto da chamada.Calls to a conditional method are either included or omitted depending on whether this symbol is defined at the point of the call. Se o símbolo for definido, a chamada será incluída; caso contrário, a chamada (incluindo a avaliação do receptor e dos parâmetros da chamada) é omitida.If the symbol is defined, the call is included; otherwise, the call (including evaluation of the receiver and parameters of the call) is omitted.

Um método condicional está sujeito às seguintes restrições:A conditional method is subject to the following restrictions:

  • O método condicional deve ser um método em um class_declaration ou struct_declaration.The conditional method must be a method in a class_declaration or struct_declaration. Ocorrerá um erro de tempo de compilação se o Conditional atributo for especificado em um método em uma declaração de interface.A compile-time error occurs if the Conditional attribute is specified on a method in an interface declaration.
  • O método condicional deve ter um tipo de retorno de void .The conditional method must have a return type of void.
  • O método condicional não deve ser marcado com o override modificador.The conditional method must not be marked with the override modifier. Um método condicional pode ser marcado com o virtual modificador, no entanto.A conditional method may be marked with the virtual modifier, however. As substituições desse método são implicitamente condicionais e não devem ser marcadas explicitamente com um Conditional atributo.Overrides of such a method are implicitly conditional, and must not be explicitly marked with a Conditional attribute.
  • O método condicional não deve ser uma implementação de um método de interface.The conditional method must not be an implementation of an interface method. Caso contrário, ocorrerá um erro de tempo de compilação.Otherwise, a compile-time error occurs.

Além disso, ocorrerá um erro de tempo de compilação se um método condicional for usado em um delegate_creation_expression.In addition, a compile-time error occurs if a conditional method is used in a delegate_creation_expression. O exemploThe example

#define DEBUG

using System;
using System.Diagnostics;

class Class1 
{
    [Conditional("DEBUG")]
    public static void M() {
        Console.WriteLine("Executed Class1.M");
    }
}

class Class2
{
    public static void Test() {
        Class1.M();
    }
}

declara Class1.M como um método condicional.declares Class1.M as a conditional method. Class2``Testo método do chama esse método.Class2's Test method calls this method. Como o símbolo de compilação condicional DEBUG é definido, se Class2.Test for chamado, ele chamará M .Since the conditional compilation symbol DEBUG is defined, if Class2.Test is called, it will call M. Se o símbolo DEBUG não tivesse sido definido, então Class2.Test não chamaria Class1.M .If the symbol DEBUG had not been defined, then Class2.Test would not call Class1.M.

É importante observar que a inclusão ou a exclusão de uma chamada para um método condicional é controlada pelos símbolos de compilação condicional no ponto da chamada.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. No exemploIn the example

Arquivo class1.cs :File class1.cs:

using System.Diagnostics;

class Class1 
{
    [Conditional("DEBUG")]
    public static void F() {
        Console.WriteLine("Executed Class1.F");
    }
}

Arquivo class2.cs :File class2.cs:

#define DEBUG

class Class2
{
    public static void G() {
        Class1.F();                // F is called
    }
}

Arquivo class3.cs :File class3.cs:

#undef DEBUG

class Class3
{
    public static void H() {
        Class1.F();                // F is not called
    }
}

as classes Class2 e Class3 cada uma contêm chamadas para o método condicional Class1.F , que é condicional com base em se DEBUG está definido ou não.the classes Class2 and Class3 each contain calls to the conditional method Class1.F, which is conditional based on whether or not DEBUG is defined. Como esse símbolo é definido no contexto de, Class2 mas não Class3 , a chamada para F no Class2 é incluída, enquanto a chamada para F in Class3 é omitida.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.

O uso de métodos condicionais em uma cadeia de herança pode ser confuso.The use of conditional methods in an inheritance chain can be confusing. As chamadas feitas a um método condicional base , do formulário base.M , estão sujeitas às regras de chamada de método condicional normais.Calls made to a conditional method through base, of the form base.M, are subject to the normal conditional method call rules. No exemploIn the example

Arquivo class1.cs :File class1.cs:

using System;
using System.Diagnostics;

class Class1 
{
    [Conditional("DEBUG")]
    public virtual void M() {
        Console.WriteLine("Class1.M executed");
    }
}

Arquivo class2.cs :File class2.cs:

using System;

class Class2: Class1
{
    public override void M() {
        Console.WriteLine("Class2.M executed");
        base.M();                        // base.M is not called!
    }
}

Arquivo class3.cs :File class3.cs:

#define DEBUG

using System;

class Class3
{
    public static void Test() {
        Class2 c = new Class2();
        c.M();                            // M is called
    }
}

Class2 inclui uma chamada para o M definido em sua classe base.Class2 includes a call to the M defined in its base class. Essa chamada é omitida porque o método base é condicional com base na presença do símbolo DEBUG , que é indefinido.This call is omitted because the base method is conditional based on the presence of the symbol DEBUG, which is undefined. Portanto, o método grava somente no console " Class2.M executed ".Thus, the method writes to the console "Class2.M executed" only. O uso criterioso de pp_declaration s pode eliminar esses problemas.Judicious use of pp_declaration s can eliminate such problems.

Classes de atributo condicionalConditional attribute classes

Uma classe de atributo (classes de atributo) decorada com um ou mais Conditional atributos é uma classe de atributo condicional.An attribute class (Attribute classes) decorated with one or more Conditional attributes is a conditional attribute class. Uma classe de atributo condicional é, portanto, associada aos símbolos de compilação condicional declarados em seus Conditional atributos.A conditional attribute class is thus associated with the conditional compilation symbols declared in its Conditional attributes. Neste exemplo:This example:

using System;
using System.Diagnostics;
[Conditional("ALPHA")]
[Conditional("BETA")]
public class TestAttribute : Attribute {}

declara TestAttribute como uma classe de atributo condicional associada aos símbolos de compilações condicionais ALPHA e BETA .declares TestAttribute as a conditional attribute class associated with the conditional compilations symbols ALPHA and BETA.

As especificações de atributo (especificação de atributo) de um atributo condicional são incluídas se um ou mais de seus símbolos de compilação condicional associados estiverem definidos no ponto de especificação, caso contrário, a especificação de atributo será omitida.Attribute specifications (Attribute specification) of a conditional attribute are included if one or more of its associated conditional compilation symbols is defined at the point of specification, otherwise the attribute specification is omitted.

É importante observar que a inclusão ou exclusão de uma especificação de atributo de uma classe de atributo condicional é controlada pelos símbolos de compilação condicional no ponto da especificação.It is important to note that the inclusion or exclusion of an attribute specification of a conditional attribute class is controlled by the conditional compilation symbols at the point of the specification. No exemploIn the example

Arquivo test.cs :File test.cs:

using System;
using System.Diagnostics;

[Conditional("DEBUG")]

public class TestAttribute : Attribute {}

Arquivo class1.cs :File class1.cs:

#define DEBUG

[Test]                // TestAttribute is specified

class Class1 {}

Arquivo class2.cs :File class2.cs:

#undef DEBUG

[Test]                 // TestAttribute is not specified

class Class2 {}

as classes Class1 e Class2 são cada uma decorada com atributo Test , que é condicional com base em se DEBUG está definida ou não.the classes Class1 and Class2 are each decorated with attribute Test, which is conditional based on whether or not DEBUG is defined. Como esse símbolo é definido no contexto de, Class1 mas não Class2 , a especificação do Test atributo em Class1 é incluída, enquanto a especificação do Test atributo em Class2 é omitida.Since this symbol is defined in the context of Class1 but not Class2, the specification of the Test attribute on Class1 is included, while the specification of the Test attribute on Class2 is omitted.

O atributo obsoletoThe Obsolete attribute

O atributo Obsolete é usado para marcar tipos e membros de tipos que não devem mais ser usados.The attribute Obsolete is used to mark types and members of types that should no longer be used.

namespace System
{
    [AttributeUsage(
        AttributeTargets.Class | 
        AttributeTargets.Struct |
        AttributeTargets.Enum | 
        AttributeTargets.Interface | 
        AttributeTargets.Delegate |
        AttributeTargets.Method | 
        AttributeTargets.Constructor |
        AttributeTargets.Property | 
        AttributeTargets.Field |
        AttributeTargets.Event,
        Inherited = false)
    ]
    public class ObsoleteAttribute: Attribute
    {
        public ObsoleteAttribute() {...}
        public ObsoleteAttribute(string message) {...}
        public ObsoleteAttribute(string message, bool error) {...}
        public string Message { get {...} }
        public bool IsError { get {...} }
    }
}

Se um programa usa um tipo ou membro que é decorado com o Obsolete atributo, o compilador emite um aviso ou um erro.If a program uses a type or member that is decorated with the Obsolete attribute, the compiler issues a warning or an error. Especificamente, o compilador emitirá um aviso se nenhum parâmetro de erro for fornecido ou se o parâmetro de erro for fornecido e tiver o valor false .Specifically, the compiler issues a warning if no error parameter is provided, or if the error parameter is provided and has the value false. O compilador emitirá um erro se o parâmetro de erro for especificado e tiver o valor true .The compiler issues an error if the error parameter is specified and has the value true.

No exemploIn the example

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

class B
{
    public void F() {}
}

class Test
{
    static void Main() {
        A a = new A();         // Warning
        a.F();
    }
}

a classe A é decorada com o Obsolete atributo.the class A is decorated with the Obsolete attribute. Cada uso de A em Main resulta em um aviso que inclui a mensagem especificada, "esta classe é obsoleta; em vez disso, use a classe B. "Each use of A in Main results in a warning that includes the specified message, "This class is obsolete; use class B instead."

Atributos de informações do chamadorCaller info attributes

Para fins como registro em log e relatórios, às vezes é útil para um membro de função obter determinadas informações de tempo de compilação sobre o código de chamada.For purposes such as logging and reporting, it is sometimes useful for a function member to obtain certain compile-time information about the calling code. Os atributos de informações do chamador fornecem uma maneira de passar essas informações de forma transparente.The caller info attributes provide a way to pass such information transparently.

Quando um parâmetro opcional é anotado com um dos atributos de informações do chamador, omitir o argumento correspondente em uma chamada não faz necessariamente com que o valor do parâmetro padrão seja substituído.When an optional parameter is annotated with one of the caller info attributes, omitting the corresponding argument in a call does not necessarily cause the default parameter value to be substituted. Em vez disso, se as informações especificadas sobre o contexto de chamada estiverem disponíveis, essas informações serão passadas como o valor do argumento.Instead, if the specified information about the calling context is available, that information will be passed as the argument value.

Por exemplo:For example:

using System.Runtime.CompilerServices

...

public void Log(
    [CallerLineNumber] int line = -1,
    [CallerFilePath]   string path = null,
    [CallerMemberName] string name = null
)
{
    Console.WriteLine((line < 0) ? "No line" : "Line "+ line);
    Console.WriteLine((path == null) ? "No file path" : path);
    Console.WriteLine((name == null) ? "No member name" : name);
}

Uma chamada para sem Log() argumentos imprimiria o número de linha e o caminho do arquivo da chamada, bem como o nome do membro no qual a chamada ocorreu.A call to Log() with no arguments would print the line number and file path of the call, as well as the name of the member within which the call occurred.

Atributos de informações do chamador podem ocorrer em parâmetros opcionais em qualquer lugar, incluindo declarações de delegado.Caller info attributes can occur on optional parameters anywhere, including in delegate declarations. No entanto, os atributos específicos de informações do chamador têm restrições sobre os tipos dos parâmetros que eles podem atribuir, de modo que sempre haverá uma conversão implícita de um valor substituído para o tipo de parâmetro.However, the specific caller info attributes have restrictions on the types of the parameters they can attribute, so that there will always be an implicit conversion from a substituted value to the parameter type.

É um erro ter o mesmo atributo de informações do chamador em um parâmetro de definição e implementação de parte de uma declaração de método parcial.It is an error to have the same caller info attribute on a parameter of both the defining and implementing part of a partial method declaration. Somente os atributos de informações do chamador na parte de definição são aplicados, enquanto os atributos de informações do chamador que ocorrem somente na parte de implementação são ignorados.Only caller info attributes in the defining part are applied, whereas caller info attributes occurring only in the implementing part are ignored.

As informações do chamador não afetam a resolução de sobrecarga.Caller information does not affect overload resolution. Como os parâmetros opcionais atribuídos ainda são omitidos do código-fonte do chamador, a resolução de sobrecarga ignora esses parâmetros da mesma maneira que ignora outros parâmetros opcionais omitidos (resolução de sobrecarga).As the attributed optional parameters are still omitted from the source code of the caller, overload resolution ignores those parameters in the same way it ignores other omitted optional parameters (Overload resolution).

As informações do chamador só são substituídas quando uma função é invocada explicitamente no código-fonte.Caller information is only substituted when a function is explicitly invoked in source code. Invocações implícitas, como chamadas de Construtor pai implícitas, não têm um local de origem e não substituirão as informações do chamador.Implicit invocations such as implicit parent constructor calls do not have a source location and will not substitute caller information. Além disso, as chamadas que são vinculadas dinamicamente não substituirão as informações do chamador.Also, calls that are dynamically bound will not substitute caller information. Quando um parâmetro de informações de chamador atribuído é omitido nesses casos, o valor padrão especificado do parâmetro é usado em vez disso.When a caller info attributed parameter is omitted in such cases, the specified default value of the parameter is used instead.

Uma exceção é Query-Expressions.One exception is query-expressions. Essas são consideradas expansões sintáticas e, se as chamadas forem expandidas para omitir parâmetros opcionais com atributos de informações do chamador, as informações do chamador serão substituídas.These are considered syntactic expansions, and if the calls they expand to omit optional parameters with caller info attributes, caller information will be substituted. O local usado é o local da cláusula de consulta da qual a chamada foi gerada.The location used is the location of the query clause which the call was generated from.

Se mais de um atributo de informações do chamador for especificado em um determinado parâmetro, eles serão preferidos na seguinte ordem: CallerLineNumber , CallerFilePath , CallerMemberName .If more than one caller info attribute is specified on a given parameter, they are preferred in the following order: CallerLineNumber, CallerFilePath, CallerMemberName.

O atributo CallerLineNumberThe CallerLineNumber attribute

O System.Runtime.CompilerServices.CallerLineNumberAttribute é permitido em parâmetros opcionais quando há uma conversão implícita padrão (conversões implícitas padrão) do valor constante int.MaxValue para o tipo do parâmetro.The System.Runtime.CompilerServices.CallerLineNumberAttribute is allowed on optional parameters when there is a standard implicit conversion (Standard implicit conversions) from the constant value int.MaxValue to the parameter's type. Isso garante que qualquer número de linha não negativo até esse valor possa ser passado sem erro.This ensures that any non-negative line number up to that value can be passed without error.

Se uma invocação de função de um local no código-fonte omitir um parâmetro opcional com o CallerLineNumberAttribute , um literal numérico representando o número de linha desse local será usado como um argumento para a invocação em vez do valor de parâmetro padrão.If a function invocation from a location in source code omits an optional parameter with the CallerLineNumberAttribute, then a numeric literal representing that location's line number is used as an argument to the invocation instead of the default parameter value.

Se a invocação abranger várias linhas, a linha escolhida será dependente de implementação.If the invocation spans multiple lines, the line chosen is implementation-dependent.

Observe que o número da linha pode ser afetado por #line Diretivas (diretivas de linha).Note that the line number may be affected by #line directives (Line directives).

O atributo CallerFilePathThe CallerFilePath attribute

O System.Runtime.CompilerServices.CallerFilePathAttribute é permitido em parâmetros opcionais quando há uma conversão implícita padrão (conversões implícitas padrão) de string para o tipo do parâmetro.The System.Runtime.CompilerServices.CallerFilePathAttribute is allowed on optional parameters when there is a standard implicit conversion (Standard implicit conversions) from string to the parameter's type.

Se uma invocação de função de um local no código-fonte omitir um parâmetro opcional com o CallerFilePathAttribute , um literal de cadeia de caracteres representando o caminho do arquivo desse local será usado como um argumento para a invocação em vez do valor de parâmetro padrão.If a function invocation from a location in source code omits an optional parameter with the CallerFilePathAttribute, then a string literal representing that location's file path is used as an argument to the invocation instead of the default parameter value.

O formato do caminho do arquivo é dependente de implementação.The format of the file path is implementation-dependent.

Observe que o caminho do arquivo pode ser afetado por #line Diretivas (diretivas de linha).Note that the file path may be affected by #line directives (Line directives).

O atributo CallerMemberNameThe CallerMemberName attribute

O System.Runtime.CompilerServices.CallerMemberNameAttribute é permitido em parâmetros opcionais quando há uma conversão implícita padrão (conversões implícitas padrão) de string para o tipo do parâmetro.The System.Runtime.CompilerServices.CallerMemberNameAttribute is allowed on optional parameters when there is a standard implicit conversion (Standard implicit conversions) from string to the parameter's type.

Se uma invocação de função de um local dentro do corpo de um membro de função ou dentro de um atributo aplicado ao próprio membro da função ou seu tipo de retorno, parâmetros ou parâmetros de tipo no código-fonte omitir um parâmetro opcional com o CallerMemberNameAttribute , um literal de cadeia de caracteres representando o nome desse membro será usado como um argumento para a invocação em vez do valor de parâmetro padrão.If a function invocation from a location within the body of a function member or within an attribute applied to the function member itself or its return type, parameters or type parameters in source code omits an optional parameter with the CallerMemberNameAttribute, then a string literal representing the name of that member is used as an argument to the invocation instead of the default parameter value.

Para invocações que ocorrem em métodos genéricos, somente o nome do método em si é usado, sem a lista de parâmetros de tipo.For invocations that occur within generic methods, only the method name itself is used, without the type parameter list.

Para invocações que ocorrem em implementações de membro de interface explícitas, somente o nome do método em si é usado, sem a qualificação da interface anterior.For invocations that occur within explicit interface member implementations, only the method name itself is used, without the preceding interface qualification.

Para invocações que ocorrem em acessadores de propriedade ou evento, o nome de membro usado é o próprio evento ou propriedade.For invocations that occur within property or event accessors, the member name used is that of the property or event itself.

Para invocações que ocorrem dentro de acessadores do indexador, o nome do membro usado é fornecido por um IndexerNameAttribute (o atributo IndexerName) no membro do indexador, se presente, ou o nome padrão Item também.For invocations that occur within indexer accessors, the member name used is that supplied by an IndexerNameAttribute (The IndexerName attribute) on the indexer member, if present, or the default name Item otherwise.

Para invocações que ocorrem em declarações de construtores de instância, construtores estáticos, destruidores e operadores, o nome de membro usado é dependente de implementação.For invocations that occur within declarations of instance constructors, static constructors, destructors and operators the member name used is implementation-dependent.

Atributos para interoperaçãoAttributes for Interoperation

Observação: Esta seção é aplicável somente à implementação de Microsoft .NET do C#.Note: This section is applicable only to the Microsoft .NET implementation of C#.

Interoperação com componentes COM e Win32Interoperation with COM and Win32 components

O tempo de execução do .NET fornece um grande número de atributos que permitem que programas em C# interoperem com componentes escritos usando DLLs COM e Win32.The .NET run-time provides a large number of attributes that enable C# programs to interoperate with components written using COM and Win32 DLLs. Por exemplo, o DllImport atributo pode ser usado em um static extern método para indicar que a implementação do método deve ser encontrada em uma DLL Win32.For example, the DllImport attribute can be used on a static extern method to indicate that the implementation of the method is to be found in a Win32 DLL. Esses atributos são encontrados no System.Runtime.InteropServices namespace e a documentação detalhada para esses atributos é encontrada na documentação do tempo de execução do .net.These attributes are found in the System.Runtime.InteropServices namespace, and detailed documentation for these attributes is found in the .NET runtime documentation.

Interoperação com outras linguagens .NETInteroperation with other .NET languages

O atributo IndexerNameThe IndexerName attribute

Os indexadores são implementados no .NET usando propriedades indexadas e têm um nome nos metadados do .NET.Indexers are implemented in .NET using indexed properties, and have a name in the .NET metadata. Se nenhum IndexerName atributo estiver presente para um indexador, o nome Item será usado por padrão.If no IndexerName attribute is present for an indexer, then the name Item is used by default. O IndexerName atributo permite que um desenvolvedor substitua esse padrão e especifique um nome diferente.The IndexerName attribute enables a developer to override this default and specify a different name.

namespace System.Runtime.CompilerServices.CSharp
{
    [AttributeUsage(AttributeTargets.Property)]
    public class IndexerNameAttribute: Attribute
    {
        public IndexerNameAttribute(string indexerName) {...}
        public string Value { get {...} } 
    }
}