IntroduçãoIntroduction

O C# (pronuncia-se "C Sharp") é uma linguagem de programação simples, moderna, orientada a objeto e fortemente tipada.C# (pronounced "See Sharp") is a simple, modern, object-oriented, and type-safe programming language. C#tem suas raízes na família C de idiomas e será imediatamente familiar para os programadores de C++c, e Java.C# has its roots in the C family of languages and will be immediately familiar to C, C++, and Java programmers. C#é padronizado pela ECMA International como o padrão ECMA-334 e pelo ISO/IEC como o padrão iso/IEC 23270 .C# is standardized by ECMA International as the ECMA-334 standard and by ISO/IEC as the ISO/IEC 23270 standard. O compilador C# da Microsoft para o .NET Framework é uma implementação de acordo com ambos os padrões.Microsoft's C# compiler for the .NET Framework is a conforming implementation of both of these standards.

O C# é uma linguagem orientada a objeto, mas inclui ainda suporte para programação orientada a componentes.C# is an object-oriented language, but C# further includes support for component-oriented programming. O design de software atual depende cada vez mais dos componentes de software na forma de pacotes independentes e autodescritivos de funcionalidade.Contemporary software design increasingly relies on software components in the form of self-contained and self-describing packages of functionality. O principal é que esses componentes apresentam um modelo de programação com propriedades, métodos e eventos; eles têm atributos que fornecem informações declarativas sobre o componente; e incorporam sua própria documentação.Key to such components is that they present a programming model with properties, methods, and events; they have attributes that provide declarative information about the component; and they incorporate their own documentation. C#fornece construções de linguagem para dar suporte direto a esses conceitos C# , fazendo uma linguagem muito natural para criar e usar componentes de software.C# provides language constructs to directly support these concepts, making C# a very natural language in which to create and use software components.

Vários recursos de C# auxiliam na construção de aplicativos robustos e duráveis: A coleta de lixo recupera automaticamente a memória ocupada por objetos não utilizados; a manipulação de exceção fornece uma abordagem estruturada e extensível para detecção e recuperação de erros; e o design de tipo seguro da linguagem torna impossível a leitura de variáveis não inicializadas, para indexar matrizes além de seus limites ou para executar conversões de tipo desmarcadas.Several C# features aid in the construction of robust and durable applications: Garbage collection automatically reclaims memory occupied by unused objects; exception handling provides a structured and extensible approach to error detection and recovery; and the type-safe design of the language makes it impossible to read from uninitialized variables, to index arrays beyond their bounds, or to perform unchecked type casts.

C# tem um sistema de tipo unificado.C# has a unified type system. Todos os tipos do C#, incluindo tipos primitivos, como int e double, herdam de um único tipo de object raiz.All C# types, including primitive types such as int and double, inherit from a single root object type. Assim, todos os tipos compartilham um conjunto de operações comuns, e valores de qualquer tipo podem ser armazenados, transportados e operados de maneira consistente.Thus, all types share a set of common operations, and values of any type can be stored, transported, and operated upon in a consistent manner. Além disso, C# oferece suporte a tipos de referência e tipos de valor definidos pelo usuário, permitindo a alocação dinâmica de objetos, bem como o armazenamento em linha de estruturas leves.Furthermore, C# supports both user-defined reference types and value types, allowing dynamic allocation of objects as well as in-line storage of lightweight structures.

Para garantir que C# os programas e as bibliotecas possam evoluir ao longo do tempo de maneira compatível, muito ênfase foi colocado no C#design do controle de versão .To ensure that C# programs and libraries can evolve over time in a compatible manner, much emphasis has been placed on versioning in C#'s design. Muitas linguagens de programação prestam pouca atenção a esse problema e, como resultado, programas escritos nessas linguagens quebram com mais frequência do que o necessário quando versões mais recentes das bibliotecas dependentes são introduzidas.Many programming languages pay little attention to this issue, and, as a result, programs written in those languages break more often than necessary when newer versions of dependent libraries are introduced. Aspectos do C#design de do que foram influenciados diretamente pelas considerações de controle de virtual versão override incluem os modificadores and separados, as regras para resolução de sobrecarga de método e suporte para declarações de membro de interface explícitas.Aspects of C#'s design that were directly influenced by versioning considerations include the separate virtual and override modifiers, the rules for method overload resolution, and support for explicit interface member declarations.

O restante deste capítulo descreve os recursos essenciais do C# idioma.The rest of this chapter describes the essential features of the C# language. Embora os capítulos posteriores descrevam as regras e exceções em uma maneira mais detalhada e, às vezes, matemática, este capítulo busca clareza e brevidade às custas da conclusão.Although later chapters describe rules and exceptions in a detail-oriented and sometimes mathematical manner, this chapter strives for clarity and brevity at the expense of completeness. A intenção é fornecer ao leitor uma introdução à linguagem que facilitará a gravação de programas antigos e a leitura de capítulos posteriores.The intent is to provide the reader with an introduction to the language that will facilitate the writing of early programs and the reading of later chapters.

Hello worldHello world

O programa "Hello, World" é usado tradicionalmente para introduzir uma linguagem de programação.The "Hello, World" program is traditionally used to introduce a programming language. Este é para C#:Here it is in C#:

using System;

class Hello
{
    static void Main() {
        Console.WriteLine("Hello, World");
    }
}

Os arquivos de origem em C# normalmente têm a extensão de arquivo .cs.C# source files typically have the file extension .cs. Supondo que o programa "Olá, mundo" esteja armazenado no arquivo hello.cs, o programa pode ser compilado com o compilador C# da Microsoft usando a linha de comandoAssuming that the "Hello, World" program is stored in the file hello.cs, the program can be compiled with the Microsoft C# compiler using the command line

csc hello.cs

que produz um assembly executável chamado hello.exe.which produces an executable assembly named hello.exe. A saída produzida por este aplicativo quando é executada éThe output produced by this application when it is run is

Hello, World

O programa "Hello, World" começa com uma diretiva using que faz referência ao namespace System.The "Hello, World" program starts with a using directive that references the System namespace. Namespaces fornecem um meio hierárquico de organizar bibliotecas e programas em C#.Namespaces provide a hierarchical means of organizing C# programs and libraries. Os namespaces contêm tipos e outros namespaces — por exemplo, o namespace System contém uma quantidade de tipos, como a classe Console referenciada no programa e diversos outros namespaces, como IO e Collections.Namespaces contain types and other namespaces—for example, the System namespace contains a number of types, such as the Console class referenced in the program, and a number of other namespaces, such as IO and Collections. A diretiva using que faz referência a um determinado namespace permite o uso não qualificado dos tipos que são membros desse namespace.A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. Devido à diretiva using, o programa pode usar Console.WriteLine como um atalho para System.Console.WriteLine.Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine.

A classe Hello declarada pelo programa "Hello, World" tem um único membro, o método chamado Main.The Hello class declared by the "Hello, World" program has a single member, the method named Main. O Main método é declarado com o static modificador.The Main method is declared with the static modifier. Embora os métodos de instância possam fazer referência a uma determinada instância de objeto delimitador usando a palavra-chave this, métodos estáticos operam sem referência a um objeto específico.While instance methods can reference a particular enclosing object instance using the keyword this, static methods operate without reference to a particular object. Por convenção, um método estático denominado Main serve como ponto de entrada de um programa.By convention, a static method named Main serves as the entry point of a program.

A saída do programa é produzida pelo método WriteLine da classe Console no namespace System.The output of the program is produced by the WriteLine method of the Console class in the System namespace. Essa classe é fornecida pelo .NET Framework bibliotecas de classe, que, por padrão, são automaticamente referenciadas pelo compilador C# da Microsoft.This class is provided by the .NET Framework class libraries, which, by default, are automatically referenced by the Microsoft C# compiler. Observe que C# ela própria não tem uma biblioteca de tempo de execução separada.Note that C# itself does not have a separate runtime library. Em vez disso, o .NET Framework é a biblioteca C#de tempo de execução do.Instead, the .NET Framework is the runtime library of C#.

Estrutura do programaProgram structure

Os principais conceitos organizacionais em C# são programas, namespaces, tipos, membros e assemblies.The key organizational concepts in C# are programs, namespaces, types, members, and assemblies. Os programas C# consistem em um ou mais arquivos de origem.C# programs consist of one or more source files. Os programas declaram tipos que contêm membros e podem ser organizados em namespaces.Programs declare types, which contain members and can be organized into namespaces. Classes e interfaces são exemplos de tipos.Classes and interfaces are examples of types. Campos, métodos, propriedades e eventos são exemplos de membros.Fields, methods, properties, and events are examples of members. Quando os programas em C# são compilados, eles são empacotados fisicamente em assemblies.When C# programs are compiled, they are physically packaged into assemblies. Normalmente, os assemblies têm a .exe extensão .dllde arquivo ou, dependendo se eles implementam aplicativos ou bibliotecas.Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or libraries.

O exemploThe example

using System;

namespace Acme.Collections
{
    public class Stack
    {
        Entry top;

        public void Push(object data) {
            top = new Entry(top, data);
        }

        public object Pop() {
            if (top == null) throw new InvalidOperationException();
            object result = top.data;
            top = top.next;
            return result;
        }

        class Entry
        {
            public Entry next;
            public object data;
    
            public Entry(Entry next, object data) {
                this.next = next;
                this.data = data;
            }
        }
    }
}

declara uma classe chamada Stack em um namespace chamado. Acme.Collectionsdeclares a class named Stack in a namespace called Acme.Collections. O nome totalmente qualificado dessa classe é Acme.Collections.Stack.The fully qualified name of this class is Acme.Collections.Stack. A classe contém vários membros: um campo chamado top, dois métodos chamados Push e Pop e uma classe aninhada chamada Entry.The class contains several members: a field named top, two methods named Push and Pop, and a nested class named Entry. A classe Entry ainda contém três membros: um campo chamado next, um campo chamado datae um construtor.The Entry class further contains three members: a field named next, a field named data, and a constructor. Supondo que o código-fonte do exemplo seja armazenado no arquivo acme.cs, a linha de comandoAssuming that the source code of the example is stored in the file acme.cs, the command line

csc /t:library acme.cs

compila o exemplo como uma biblioteca (o código sem um ponto de entrada Main) e produz um assembly denominado acme.dll.compiles the example as a library (code without a Main entry point) and produces an assembly named acme.dll.

Os assemblies contêm código executável na forma de instruções de Il ( linguagem intermediária ) e informações simbólicas na forma de metadados.Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. Antes de ser executado, o código de IL em um assembly é automaticamente convertido em código específico do processador pelo compilador JIT (Just-In-Time) do .NET Common Language Runtime.Before it is executed, the IL code in an assembly is automatically converted to processor-specific code by the Just-In-Time (JIT) compiler of .NET Common Language Runtime.

Como um assembly é uma unidade autodescritiva da funcionalidade que contém o código e os metadados, não é necessário de diretivas #include e arquivos de cabeçalho no C#.Because an assembly is a self-describing unit of functionality containing both code and metadata, there is no need for #include directives and header files in C#. Os tipos públicos e os membros contidos em um assembly específico são disponibilizados em um programa C# simplesmente fazendo referência a esse assembly ao compilar o programa.The public types and members contained in a particular assembly are made available in a C# program simply by referencing that assembly when compiling the program. Por exemplo, esse programa usa a classe Acme.Collections.Stack do assembly acme.dll:For example, this program uses the Acme.Collections.Stack class from the acme.dll assembly:

using System;
using Acme.Collections;

class Test
{
    static void Main() {
        Stack s = new Stack();
        s.Push(1);
        s.Push(10);
        s.Push(100);
        Console.WriteLine(s.Pop());
        Console.WriteLine(s.Pop());
        Console.WriteLine(s.Pop());
    }
}

Se o programa estiver test.csarmazenado no arquivo, quando test.cs for compilado, o acme.dll assembly poderá ser referenciado usando a opção do /r compilador:If the program is stored in the file test.cs, when test.cs is compiled, the acme.dll assembly can be referenced using the compiler's /r option:

csc /r:acme.dll test.cs

Isso cria um assembly executável denominado test.exe, que, quando executado, produz a saída:This creates an executable assembly named test.exe, which, when run, produces the output:

100
10
1

O C# permite que o texto de origem de um programa seja armazenado em vários arquivos de origem.C# permits the source text of a program to be stored in several source files. Quando um programa em C# com vários arquivo é compilado, todos os arquivos de origem são processados juntos e os arquivos de origem podem referenciar livremente uns aos outros. Conceitualmente, é como se todos os arquivos de origem fossem concatenados em um arquivo grande antes de serem processados.When a multi-file C# program is compiled, all of the source files are processed together, and the source files can freely reference each other—conceptually, it is as if all the source files were concatenated into one large file before being processed. Declarações de encaminhamento nunca são necessárias em C#, porque, com poucas exceções, a ordem de declaração é insignificante.Forward declarations are never needed in C# because, with very few exceptions, declaration order is insignificant. O C# não limita um arquivo de origem para declarar somente um tipo público nem requer o nome do arquivo de origem para corresponder a um tipo declarado no arquivo de origem.C# does not limit a source file to declaring only one public type nor does it require the name of the source file to match a type declared in the source file.

Tipos e variáveisTypes and variables

Há dois tipos em C#: tipos de referência e tipos de valor.There are two kinds of types in C#: value types and reference types. As variáveis de tipos de valor contêm diretamente seus dados enquanto variáveis de tipos de referência armazenam referências a seus dados, o último sendo conhecido como objetos.Variables of value types directly contain their data whereas variables of reference types store references to their data, the latter being known as objects. Com tipos de referência, é possível que duas variáveis referenciem o mesmo objeto e, portanto, é possível que operações em uma variável afetem o objeto referenciado por outra variável.With reference types, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. Com tipos de valor, cada variável tem sua própria cópia dos dados e não é possível que operações em uma variável afetem a outra (exceto no caso de variáveis de parâmetros ref e out).With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other (except in the case of ref and out parameter variables).

C#os tipos de valor de são divididos em tipos simples, tipos de enumeração, tipos de structe tipos anuláveis, e C#os tipos de referência são divididos em tipos de classe, tipos de interface, matriz tipose tipos delegados.C#'s value types are further divided into simple types, enum types, struct types, and nullable types, and C#'s reference types are further divided into class types, interface types, array types, and delegate types.

A tabela a seguir fornece uma visão C#geral do sistema de tipos do.The following table provides an overview of C#'s type system.

CategoriaCategory DescriçãoDescription
Tipos de valorValue types Tipos simplesSimple types Integral com sinal: sbyte, short, int,longSigned integral: sbyte, short, int, long
Integral sem sinal: byte, ushort, uint,ulongUnsigned integral: byte, ushort, uint, ulong
Caracteres Unicode: charUnicode characters: char
Ponto flutuante IEEE: float, doubleIEEE floating point: float, double
Decimal de alta precisão:decimalHigh-precision decimal: decimal
Booliano: boolBoolean: bool
Tipos enumEnum types Tipos definidos pelo usuário do formulário enum E {...}User-defined types of the form enum E {...}
Tipos structStruct types Tipos definidos pelo usuário do formulário struct S {...}User-defined types of the form struct S {...}
Tipos que permitem valor nuloNullable types Extensões de todos os outros tipos de valor com um valor nullExtensions of all other value types with a null value
Tipos de referênciaReference types Tipos de classeClass types Classe base definitiva de todos os outros tipos: objectUltimate base class of all other types: object
Cadeia de caracteres Unicode: stringUnicode strings: string
Tipos definidos pelo usuário do formulário class C {...}User-defined types of the form class C {...}
Tipos de interfaceInterface types Tipos definidos pelo usuário do formulário interface I {...}User-defined types of the form interface I {...}
Tipos de matrizArray types Unidimensional e multidimensional, por exemplo, int[] e int[,]Single- and multi-dimensional, for example, int[] and int[,]
Tipos delegadosDelegate types Tipos definidos pelo usuário do formulário, por exemplo,delegate int D(...)User-defined types of the form e.g. delegate int D(...)

Os tipos integrais oito dão suporte a valores de 8 bits, 16 bits, 32 bits e 64 bits no formulário com ou sem sinal.The eight integral types provide support for 8-bit, 16-bit, 32-bit, and 64-bit values in signed or unsigned form.

Os dois tipos de ponto flutuante float , doublee, são representados usando os formatos IEEE 754 de precisão única de 32 bits e de 64 bits de precisão dupla.The two floating point types, float and double, are represented using the 32-bit single-precision and 64-bit double-precision IEEE 754 formats.

O tipo decimal é um tipo de dados de 128 bits adequado para cálculos financeiros e monetários.The decimal type is a 128-bit data type suitable for financial and monetary calculations.

C#falseo bool tipoéusadopararepresentarvaloresBoolianos—valoresquesãoou.trueC#'s bool type is used to represent boolean values—values that are either true or false.

O processamento de cadeia de caracteres e caracteres em C# usa codificação Unicode.Character and string processing in C# uses Unicode encoding. O tipo char representa uma unidade de código UTF-16 e o tipo string representa uma sequência de unidades de código UTF-16.The char type represents a UTF-16 code unit, and the string type represents a sequence of UTF-16 code units.

A tabela a seguir resume C#os tipos numéricos de.The following table summarizes C#'s numeric types.

CategoriaCategory BitsBits TipoType Intervalo/precisãoRange/Precision
Integral assinadaSigned integral 88 sbyte -128... 127-128...127
1616 short -32768... 32, 767-32,768...32,767
3232 int -2147483648... 2, 147, 483, 647-2,147,483,648...2,147,483,647
6464 long -9.223.372.036.854.775.808... 9, 223, 372, 036, 854, 775, 807-9,223,372,036,854,775,808...9,223,372,036,854,775,807
Integral sem sinalUnsigned integral 88 byte 0... 2550...255
1616 ushort 0... 65, 5350...65,535
3232 uint 0... 4, 294, 967, 2950...4,294,967,295
6464 ulong 0... 18, 446, 744, 073, 709, 551, 6150...18,446,744,073,709,551,615
Ponto flutuanteFloating point 3232 float 1,5 × 10 ^ − 45 a 3,4 × 10 ^ 38, precisão de 7 dígitos1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
6464 double 5,0 × 10 ^ − 324 a 1,7 × 10 ^ 308, precisão de 15 dígitos5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision
DecimalDecimal 128128 decimal 1,0 × 10 ^ − 28 a 7,9 × 10 ^ 28, precisão de 28 dígitos1.0 × 10^−28 to 7.9 × 10^28, 28-digit precision

Os programas em C# usam declarações de tipos para criar novos tipos.C# programs use type declarations to create new types. Uma declaração de tipo especifica o nome e os membros do novo tipo.A type declaration specifies the name and the members of the new type. C#Cinco categorias de tipos são definíveis pelo usuário: tipos de classe, tipos de struct, tipos de interface, tipos de enumeração e tipos delegados.Five of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, and delegate types.

Um tipo de classe define uma estrutura de dados que contém membros de dados (campos) e membros de função (métodos, propriedades e outros).A class type defines a data structure that contains data members (fields) and function members (methods, properties, and others). Os tipos de classe dão suporte à herança única e ao polimorfismo, mecanismos nos quais as classes derivadas podem estender e especializar as classes base.Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Um tipo struct é semelhante a um tipo de classe, pois representa uma estrutura com membros de dados e membros de função.A struct type is similar to a class type in that it represents a structure with data members and function members. No entanto, ao contrário das classes, as structs são tipos de valor e não exigem alocação de heap.However, unlike classes, structs are value types and do not require heap allocation. Os tipos de estrutura não dão suporte à herança especificada pelo usuário, e todos os tipos de structs são herdados implicitamente do tipo object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Um tipo de interface define um contrato como um conjunto nomeado de membros da função pública.An interface type defines a contract as a named set of public function members. Uma classe ou struct que implementa uma interface deve fornecer implementações dos membros da função da interface.A class or struct that implements an interface must provide implementations of the interface's function members. Uma interface pode herdar de várias interfaces base e uma classe ou estrutura pode implementar várias interfaces.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

Um tipo delegado representa referências a métodos com uma lista de parâmetros e um tipo de retorno específicos.A delegate type represents references to methods with a particular parameter list and return type. Delegados possibilitam o tratamento de métodos como entidades que podem ser atribuídos a variáveis e passadas como parâmetros.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Os delegados são parecidos com o conceito de ponteiros de função em outras linguagens, mas ao contrário dos ponteiros de função, os delegados são orientados a objetos e fortemente tipados.Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

Tipos de classe, struct, interface e delegado oferecem suporte a genéricos, no qual eles podem ser parametrizados com outros tipos.Class, struct, interface and delegate types all support generics, whereby they can be parameterized with other types.

Um tipo de enumeração é um tipo distinto com constantes nomeadas.An enum type is a distinct type with named constants. Cada tipo de enumeração tem um tipo subjacente, que deve ser um dos oito tipos integrais.Every enum type has an underlying type, which must be one of the eight integral types. O conjunto de valores de um tipo enum é o mesmo que o conjunto de valores do tipo subjacente.The set of values of an enum type is the same as the set of values of the underlying type.

O C# dá suporte a matrizes uni e multidimensionais de qualquer tipo.C# supports single- and multi-dimensional arrays of any type. Ao contrário dos tipos listados acima, os tipos de matriz não precisam ser declarados antes de serem usados.Unlike the types listed above, array types do not have to be declared before they can be used. Em vez disso, os tipos de matriz são construídos seguindo um nome de tipo entre colchetes.Instead, array types are constructed by following a type name with square brackets. Por exemplo, int[] é uma matriz unidimensional de int, int[,] é uma matriz bidimensional de inte int[][] é uma matriz unidimensional de matrizes unidimensionais do int.For example, int[] is a single-dimensional array of int, int[,] is a two-dimensional array of int, and int[][] is a single-dimensional array of single-dimensional arrays of int.

Os tipos anuláveis também não precisam ser declarados antes que possam ser usados.Nullable types also do not have to be declared before they can be used. Para cada tipo T de valor não anulável, há um tipo T?anulável correspondente, que pode conter um valor nulladicional.For each non-nullable value type T there is a corresponding nullable type T?, which can hold an additional value null. Por exemplo, int? é um tipo que pode conter qualquer número inteiro de 32 bits ou nullo valor.For instance, int? is a type that can hold any 32 bit integer or the value null.

C#o sistema de tipos do é unificado, de modo que um valor de qualquer tipo possa ser tratado como um objeto.C#'s type system is unified such that a value of any type can be treated as an object. Cada tipo no C#, direta ou indiretamente, deriva do tipo de classe object, e object é a classe base definitiva de todos os tipos.Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. Os valores de tipos de referência são tratados como objetos simplesmente exibindo os valores como tipo object.Values of reference types are treated as objects simply by viewing the values as type object. Os valores dos tipos de valor são tratados como objetos executando operações Boxing e unboxing .Values of value types are treated as objects by performing boxing and unboxing operations. No exemplo a seguir, um valor int é convertido em object e volta novamente ao int.In the following example, an int value is converted to object and back again to int.

using System;

class Test
{
    static void Main() {
        int i = 123;
        object o = i;          // Boxing
        int j = (int)o;        // Unboxing
    }
}

Quando um valor de um tipo de valor é convertido em objecttipo, uma instância de objeto, também chamada de "caixa", é alocada para conter o valor e o valor é copiado para essa caixa.When a value of a value type is converted to type object, an object instance, also called a "box," is allocated to hold the value, and the value is copied into that box. Por outro lado, quando uma object referência é convertida em um tipo de valor, é feita uma verificação de que o objeto referenciado é uma caixa do tipo de valor correto e, se a verificação for bem sucedido, o valor na caixa será copiado.Conversely, when an object reference is cast to a value type, a check is made that the referenced object is a box of the correct value type, and, if the check succeeds, the value in the box is copied out.

C#o sistema de tipos unificados da maneira efetivamente significa que os tipos de valor podem se tornar objetos "sob demanda".C#'s unified type system effectively means that value types can become objects "on demand." Devido à unificação, as bibliotecas de finalidade geral que usam o tipo object podem ser usadas com os tipos de referência e os tipos de valor.Because of the unification, general-purpose libraries that use type object can be used with both reference types and value types.

Existem vários tipos de variáveis no C#, incluindo campos, elementos de matriz, variáveis locais e parâmetros.There are several kinds of variables in C#, including fields, array elements, local variables, and parameters. As variáveis representam locais de armazenamento e cada variável tem um tipo que determina quais valores podem ser armazenados na variável, conforme mostrado na tabela a seguir.Variables represent storage locations, and every variable has a type that determines what values can be stored in the variable, as shown by the following table.

Tipo de variávelType of Variable Conteúdo possívelPossible Contents
Tipo de valor não nuloNon-nullable value type Um valor de tipo exatoA value of that exact type
Tipos de valor anulávelNullable value type Um valor nulo ou um valor desse tipo exatoA null value or a value of that exact type
object Uma referência nula, uma referência a um objeto de qualquer tipo de referência ou uma referência a um valor em caixa de qualquer tipo de valorA null reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
Tipo de classeClass type Uma referência nula, uma referência a uma instância desse tipo de classe ou uma referência a uma instância de uma classe derivada desse tipo de classeA null reference, a reference to an instance of that class type, or a reference to an instance of a class derived from that class type
Tipo de interfaceInterface type Uma referência nula, uma referência a uma instância de um tipo de classe que implementa esse tipo de interface, ou uma referência a um valor em caixa de um tipo de valor que implementa esse tipo de interfaceA null reference, a reference to an instance of a class type that implements that interface type, or a reference to a boxed value of a value type that implements that interface type
Tipo de matrizArray type Uma referência nula, uma referência a uma instância desse tipo de matriz ou uma referência a uma instância de um tipo de matriz compatívelA null reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
Tipo delegadoDelegate type Uma referência nula ou uma referência a uma instância desse tipo delegadoA null reference or a reference to an instance of that delegate type

ExpressõesExpressions

Expressões são construídas a partir de operandos e operadores.Expressions are constructed from operands and operators. Os operadores de uma expressão indicam quais operações devem ser aplicadas aos operandos.The operators of an expression indicate which operations to apply to the operands. Exemplos de operadores incluem +, -, *, / e new.Examples of operators include +, -, *, /, and new. Exemplos de operandos incluem literais, campos, variáveis locais e expressões.Examples of operands include literals, fields, local variables, and expressions.

Quando uma expressão contiver vários operadores, a precedência dos operadores controla a ordem na qual os operadores individuais são avaliados.When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. Por exemplo, a expressão x + y * z é avaliada como x + (y * z) porque o operador * tem precedência maior do que o operador +.For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the + operator.

A maioria dos operadores pode ser sobrecarregada.Most operators can be overloaded. A sobrecarga de operador permite que implementações de operador definidas pelo usuário sejam especificadas para operações em que um ou ambos os operandos são de um tipo struct ou de classe definida pelo usuário.Operator overloading permits user-defined operator implementations to be specified for operations where one or both of the operands are of a user-defined class or struct type.

A tabela a seguir resume C#os operadores, listando as categorias de operador em ordem de precedência, da mais alta para a mais baixa.The following table summarizes C#'s operators, listing the operator categories in order of precedence from highest to lowest. Operadores na mesma categoria têm a mesma precedência.Operators in the same category have equal precedence.

CategoriaCategory ExpressãoExpression DescriçãoDescription
PrimáriaPrimary x.m Acesso de membrosMember access
x(...) Invocação de método e delegadoMethod and delegate invocation
x[...] Acesso de matriz e indexadorArray and indexer access
x++ Pós-incrementoPost-increment
x-- Pós-decrementoPost-decrement
new T(...) Criação de objeto e delegadoObject and delegate creation
new T(...){...} Criação de objeto com inicializadorObject creation with initializer
new {...} Inicializador de objeto anônimoAnonymous object initializer
new T[...] Criação de matrizArray creation
typeof(T) Obter objeto System.Type para TObtain System.Type object for T
checked(x) Avalia expressão no contexto selecionadoEvaluate expression in checked context
unchecked(x) Avalia expressão no contexto desmarcadoEvaluate expression in unchecked context
default(T) Obter valor padrão do tipo TObtain default value of type T
delegate {...} Função anônima (método anônimo)Anonymous function (anonymous method)
UnárioUnary +x IdentidadeIdentity
-x NegaçãoNegation
!x Negação lógicaLogical negation
~x Negação bit a bitBitwise negation
++x Pré-incrementoPre-increment
--x Pré-decrementoPre-decrement
(T)x Converter explicitamente x no tipo TExplicitly convert x to type T
await x Aguardar assincronamente x para concluirAsynchronously wait for x to complete
MultiplicativoMultiplicative x * y MultiplicaçãoMultiplication
x / y DivisãoDivision
x % y RestanteRemainder
AditivoAdditive x + y Adição, concatenação de cadeia de caracteres, combinação de delegadosAddition, string concatenation, delegate combination
x - y Subtração, remoção de delegadoSubtraction, delegate removal
ShiftShift x << y Shift esquerdoShift left
x >> y Shift direitoShift right
Teste de tipo e relacionalRelational and type testing x < y Menor queLess than
x > y Maior queGreater than
x <= y Menor ou igual aLess than or equal
x >= y Maior que ou igual aGreater than or equal
x is T Retorna true se x for um T, caso contrário, falseReturn true if x is a T, false otherwise
x as T Retorna x digitado como T ou null, se x não for um TReturn x typed as T, or null if x is not a T
IgualdadeEquality x == y Igual aEqual
x != y Diferente deNot equal
AND lógicoLogical AND x & y AND bit a bit inteiro, AND lógico boolianoInteger bitwise AND, boolean logical AND
XOR lógicoLogical XOR x ^ y XOR bit a bit inteiro, XOR lógico boolianoInteger bitwise XOR, boolean logical XOR
OR lógicoLogical OR x | y OR bit a bit inteiro, OR lógico boolianoInteger bitwise OR, boolean logical OR
AND condicionalConditional AND x && y Avalia somente se xfor y``trueEvaluates y only if x is true
OR condicionalConditional OR x || y Avalia somente se xfor y``falseEvaluates y only if x is false
Coalescência nulaNull coalescing x ?? y Avalia como y x se x énull, para de outra formaEvaluates to y if x is null, to x otherwise
CondicionalConditional x ? y : z Avalia y se x for true, z se x for falseEvaluates y if x is true, z if x is false
Atribuição ou função anônimaAssignment or anonymous function x = y AtribuiçãoAssignment
x op= y Atribuição composta; os operadores com *= suporte são /= %= += -= <<= >>= &= ^=|=Compound assignment; supported operators are *= /= %= += -= <<= >>= &= ^= |=
(T x) => y Função anônima (expressão lambda)Anonymous function (lambda expression)

InstruçõesStatements

As ações de um programa são expressas usando instruções.The actions of a program are expressed using statements. O C# oferece suporte a vários tipos diferentes de instruções, algumas delas definidas em termos de instruções inseridas.C# supports several different kinds of statements, a number of which are defined in terms of embedded statements.

Um bloco permite a produção de várias instruções em contextos nos quais uma única instrução é permitida.A block permits multiple statements to be written in contexts where a single statement is allowed. Um bloco é composto por uma lista de instruções escritas entre os delimitadores { e }.A block consists of a list of statements written between the delimiters { and }.

Instruções de declaração são usadas para declarar constantes e variáveis locais.Declaration statements are used to declare local variables and constants.

Instruções de expressão são usadas para avaliar expressões.Expression statements are used to evaluate expressions. As expressões que podem ser usadas como instruções incluem invocações de método, alocações de objeto usando o new operador, atribuições = usando e os operadores de atribuição compostos, operações de incremento e decréscimo usando o ++operadores -- e e expressões Await.Expressions that can be used as statements include method invocations, object allocations using the new operator, assignments using = and the compound assignment operators, increment and decrement operations using the ++ and -- operators and await expressions.

Instruções de seleção são usadas para selecionar uma dentre várias instruções possíveis para execução com base no valor de alguma expressão.Selection statements are used to select one of a number of possible statements for execution based on the value of some expression. Neste grupo estão as instruções if e switch.In this group are the if and switch statements.

Instruções de iteração são usadas para executar repetidamente uma instrução inserida.Iteration statements are used to repeatedly execute an embedded statement. Neste grupo estão as instruções while, do, for e foreach.In this group are the while, do, for, and foreach statements.

Instruções de salto são usadas para transferir o controle.Jump statements are used to transfer control. Neste grupo estão as instruções break, continue, goto, throw, return e yield.In this group are the break, continue, goto, throw, return, and yield statements.

A instrução try... catch é usada para capturar exceções que ocorrem durante a execução de um bloco, e a instrução try... finally é usada para especificar o código de finalização que é executado sempre, se uma exceção ocorrer ou não.The try...catch statement is used to catch exceptions that occur during execution of a block, and the try...finally statement is used to specify finalization code that is always executed, whether an exception occurred or not.

As checked instruções unchecked e são usadas para controlar o contexto de verificação de estouro para operações aritméticas de tipo integral e conversões.The checked and unchecked statements are used to control the overflow checking context for integral-type arithmetic operations and conversions.

A instrução lock é usada para obter o bloqueio de exclusão mútua para um determinado objeto, executar uma instrução e, em seguida, liberar o bloqueio.The lock statement is used to obtain the mutual-exclusion lock for a given object, execute a statement, and then release the lock.

A instrução using é usada para obter um recurso, executar uma instrução e, em seguida, descartar esse recurso.The using statement is used to obtain a resource, execute a statement, and then dispose of that resource.

Veja abaixo exemplos de cada tipo de instruçãoBelow are examples of each kind of statement

Declarações de variáveis locaisLocal variable declarations

static void Main() {
   int a;
   int b = 2, c = 3;
   a = 1;
   Console.WriteLine(a + b + c);
}

Declaração de constante localLocal constant declaration

static void Main() {
    const float pi = 3.1415927f;
    const int r = 25;
    Console.WriteLine(pi * r * r);
}

Instrução de expressãoExpression statement

static void Main() {
    int i;
    i = 123;                // Expression statement
    Console.WriteLine(i);   // Expression statement
    i++;                    // Expression statement
    Console.WriteLine(i);   // Expression statement
}

Instrução ifif statement

static void Main(string[] args) {
    if (args.Length == 0) {
        Console.WriteLine("No arguments");
    }
    else {
        Console.WriteLine("One or more arguments");
    }
}

Instrução switchswitch statement

static void Main(string[] args) {
    int n = args.Length;
    switch (n) {
        case 0:
            Console.WriteLine("No arguments");
            break;
        case 1:
            Console.WriteLine("One argument");
            break;
        default:
            Console.WriteLine("{0} arguments", n);
            break;
    }
}

Instrução whilewhile statement

static void Main(string[] args) {
    int i = 0;
    while (i < args.Length) {
        Console.WriteLine(args[i]);
        i++;
    }
}

Instrução dodo statement

static void Main() {
    string s;
    do {
        s = Console.ReadLine();
        if (s != null) Console.WriteLine(s);
    } while (s != null);
}

Instrução forfor statement

static void Main(string[] args) {
    for (int i = 0; i < args.Length; i++) {
        Console.WriteLine(args[i]);
    }
}

Instrução foreachforeach statement

static void Main(string[] args) {
    foreach (string s in args) {
        Console.WriteLine(s);
    }
}

Instrução breakbreak statement

static void Main() {
    while (true) {
        string s = Console.ReadLine();
        if (s == null) break;
        Console.WriteLine(s);
    }
}

Instrução continuecontinue statement

static void Main(string[] args) {
    for (int i = 0; i < args.Length; i++) {
        if (args[i].StartsWith("/")) continue;
        Console.WriteLine(args[i]);
    }
}

Instrução gotogoto statement

static void Main(string[] args) {
    int i = 0;
    goto check;
    loop:
    Console.WriteLine(args[i++]);
    check:
    if (i < args.Length) goto loop;
}

Instrução returnreturn statement

static int Add(int a, int b) {
    return a + b;
}

static void Main() {
    Console.WriteLine(Add(1, 2));
    return;
}

Instrução yieldyield statement

static IEnumerable<int> Range(int from, int to) {
    for (int i = from; i < to; i++) {
        yield return i;
    }
    yield break;
}

static void Main() {
    foreach (int x in Range(-10,10)) {
        Console.WriteLine(x);
    }
}

throwinstruções try ethrow and try statements

static double Divide(double x, double y) {
    if (y == 0) throw new DivideByZeroException();
    return x / y;
}

static void Main(string[] args) {
    try {
        if (args.Length != 2) {
            throw new Exception("Two numbers required");
        }
        double x = double.Parse(args[0]);
        double y = double.Parse(args[1]);
        Console.WriteLine(Divide(x, y));
    }
    catch (Exception e) {
        Console.WriteLine(e.Message);
    }
    finally {
        Console.WriteLine("Good bye!");
    }
}

checkedinstruções unchecked echecked and unchecked statements

static void Main() {
    int i = int.MaxValue;
    checked {
        Console.WriteLine(i + 1);        // Exception
    }
    unchecked {
        Console.WriteLine(i + 1);        // Overflow
    }
}

Instrução locklock statement

class Account
{
    decimal balance;
    public void Withdraw(decimal amount) {
        lock (this) {
            if (amount > balance) {
                throw new Exception("Insufficient funds");
            }
            balance -= amount;
        }
    }
}

Instrução usingusing statement

static void Main() {
    using (TextWriter w = File.CreateText("test.txt")) {
        w.WriteLine("Line one");
        w.WriteLine("Line two");
        w.WriteLine("Line three");
    }
}

Classes e objetosClasses and objects

As classes são os tipos do C# mais fundamentais.Classes are the most fundamental of C#'s types. Uma classe é uma estrutura de dados que combina ações (métodos e outros membros da função) e estado (campos) em uma única unidade.A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. Uma classe fornece uma definição para instâncias da classe criadas dinamicamente, também conhecidas como objetos.A class provides a definition for dynamically created instances of the class, also known as objects. As classes dão suporte à herança e polimorfismo, mecanismos nos quais classes derivadas podem estender e especializar classes base.Classes support inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Novas classes são criadas usando declarações de classe.New classes are created using class declarations. Uma declaração de classe inicia com um cabeçalho que especifica os atributos e modificadores de classe, o nome da classe, a classe base (se fornecida) e as interfaces implementadas pela classe.A class declaration starts with a header that specifies the attributes and modifiers of the class, the name of the class, the base class (if given), and the interfaces implemented by the class. O cabeçalho é seguido pelo corpo da classe, que consiste em uma lista de declarações de membro escrita entre os delimitadores { e }.The header is followed by the class body, which consists of a list of member declarations written between the delimiters { and }.

A seguir está uma declaração de uma classe simples chamada Point:The following is a declaration of a simple class named Point:

public class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Instâncias de classes são criadas usando o operador new, que aloca memória para uma nova instância, chama um construtor para inicializar a instância e retorna uma referência à instância.Instances of classes are created using the new operator, which allocates memory for a new instance, invokes a constructor to initialize the instance, and returns a reference to the instance. As instruções a seguir criam Point dois objetos e armazenam referências a esses objetos em duas variáveis:The following statements create two Point objects and store references to those objects in two variables:

Point p1 = new Point(0, 0);
Point p2 = new Point(10, 20);

A memória ocupada por um objeto é recuperada automaticamente quando o objeto não está mais em uso.The memory occupied by an object is automatically reclaimed when the object is no longer in use. Não é necessário nem possível desalocar explicitamente os objetos em C#.It is neither necessary nor possible to explicitly deallocate objects in C#.

MembrosMembers

Os membros de uma classe são membros estáticos ou membros de instância.The members of a class are either static members or instance members. Os membros estáticos pertencem às classes e os membros de instância pertencem aos objetos (instâncias de classes).Static members belong to classes, and instance members belong to objects (instances of classes).

A tabela a seguir fornece uma visão geral dos tipos de membros que uma classe pode conter.The following table provides an overview of the kinds of members a class can contain.

AssociadoMember DescriçãoDescription
ConstantesConstants Valores constantes associados à classeConstant values associated with the class
CamposFields Variáveis de classeVariables of the class
MétodosMethods Os cálculos e as ações que podem ser executados pela classeComputations and actions that can be performed by the class
PropriedadesProperties Ações associadas à leitura e à gravação de propriedades nomeadas da classeActions associated with reading and writing named properties of the class
IndexadoresIndexers Ações associadas a instâncias de indexação da classe como uma matrizActions associated with indexing instances of the class like an array
EventosEvents Notificações que podem ser geradas pela classeNotifications that can be generated by the class
OperadoresOperators Operadores de conversões e expressão com suporte da classeConversions and expression operators supported by the class
ConstrutoresConstructors Ações necessárias para inicializar instâncias da classe ou a própria classeActions required to initialize instances of the class or the class itself
DestruidoresDestructors Ações a serem executadas antes de as instâncias da classe serem descartadas permanentementeActions to perform before instances of the class are permanently discarded
TiposTypes Tipos aninhados declarados pela classeNested types declared by the class

AcessibilidadeAccessibility

Cada membro de uma classe tem uma acessibilidade associada, que controla as regiões de texto do programa que são capazes de acessar o membro.Each member of a class has an associated accessibility, which controls the regions of program text that are able to access the member. Há cinco formas possíveis de acessibilidade.There are five possible forms of accessibility. Esses métodos estão resumidos na tabela a seguir.These are summarized in the following table.

AcessibilidadeAccessibility SignificadoMeaning
public Acesso não limitadoAccess not limited
protected Acesso limitado a essa classe ou classes derivadas dessa classeAccess limited to this class or classes derived from this class
internal Acesso limitado a este programaAccess limited to this program
protected internal Acesso limitado a esse programa ou a classes derivadas dessa classeAccess limited to this program or classes derived from this class
private Acesso limitado a essa classeAccess limited to this class

Parâmetros de tipoType parameters

Uma definição de classe pode especificar um conjunto de parâmetros de tipo seguindo o nome da classe com colchetes angulares com uma lista de nomes de parâmetro de tipo.A class definition may specify a set of type parameters by following the class name with angle brackets enclosing a list of type parameter names. Os parâmetros de tipo podem ser usados no corpo das declarações de classe para definir os membros da classe.The type parameters can the be used in the body of the class declarations to define the members of the class. No exemplo a seguir, os parâmetros de tipo de Pair são TFirst e TSecond:In the following example, the type parameters of Pair are TFirst and TSecond:

public class Pair<TFirst,TSecond>
{
    public TFirst First;
    public TSecond Second;
}

Um tipo de classe declarado para pegar parâmetros de tipo é chamado de tipo de classe genérico.A class type that is declared to take type parameters is called a generic class type. Tipos de struct, de interface e de delegado também podem ser genéricos.Struct, interface and delegate types can also be generic.

Quando a classe genérica é usada, os argumentos de tipo devem ser fornecidos para cada um dos parâmetros de tipo:When the generic class is used, type arguments must be provided for each of the type parameters:

Pair<int,string> pair = new Pair<int,string> { First = 1, Second = "two" };
int i = pair.First;     // TFirst is int
string s = pair.Second; // TSecond is string

Um tipo genérico com argumentos de tipo fornecidos, Pair<int,string> como acima, é chamado de tipo construído.A generic type with type arguments provided, like Pair<int,string> above, is called a constructed type.

Classes baseBase classes

Uma declaração de classe pode especificar uma classe base, seguindo os parâmetros de nome da classe e tipo com dois-pontos e o nome da classe base.A class declaration may specify a base class by following the class name and type parameters with a colon and the name of the base class. Omitir uma especificação de classe base é o mesmo que derivar do object de tipo.Omitting a base class specification is the same as deriving from type object. No exemplo a seguir, a classe base de Point3D é Point e a classe base de Point é object:In the following example, the base class of Point3D is Point, and the base class of Point is object:

public class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class Point3D: Point
{
    public int z;

    public Point3D(int x, int y, int z): base(x, y) {
        this.z = z;
    }
}

Uma classe herda os membros de sua classe base.A class inherits the members of its base class. Herança significa que uma classe implicitamente contém todos os membros de sua classe base, exceto para os construtores estáticos e de instância, e os destruidores da classe base.Inheritance means that a class implicitly contains all members of its base class, except for the instance and static constructors, and the destructors of the base class. Uma classe derivada pode adicionar novos membros aos que ela herda, mas ela não pode remover a definição de um membro herdado.A derived class can add new members to those it inherits, but it cannot remove the definition of an inherited member. No exemplo anterior, Point3D herda os campos x e y de Point e cada instância Point3D contém três campos: x, y e z.In the previous example, Point3D inherits the x and y fields from Point, and every Point3D instance contains three fields, x, y, and z.

Existe uma conversão implícita de um tipo de classe para qualquer um de seus tipos de classe base.An implicit conversion exists from a class type to any of its base class types. Portanto, uma variável de um tipo de classe pode referenciar uma instância dessa classe ou uma instância de qualquer classe derivada.Therefore, a variable of a class type can reference an instance of that class or an instance of any derived class. Por exemplo, dadas as declarações de classe anteriores, uma variável do tipo Point podem referenciar um Point ou um Point3D:For example, given the previous class declarations, a variable of type Point can reference either a Point or a Point3D:

Point a = new Point(10, 20);
Point b = new Point3D(10, 20, 30);

CamposFields

Um campo é uma variável associada a uma classe ou com uma instância de uma classe.A field is a variable that is associated with a class or with an instance of a class.

Um campo declarado com o static modificador define um campo estático.A field declared with the static modifier defines a static field. Um campo estático identifica exatamente um local de armazenamento.A static field identifies exactly one storage location. Não importa quantas instâncias de uma classe são criadas, há sempre apenas uma cópia de um campo estático.No matter how many instances of a class are created, there is only ever one copy of a static field.

Um campo declarado sem o static modificador define um campo de instância.A field declared without the static modifier defines an instance field. Cada instância de uma classe contém uma cópia separada de todos os campos de instância dessa classe.Every instance of a class contains a separate copy of all the instance fields of that class.

No exemplo a seguir, cada instância da classe Color tem uma cópia separada dos campos de instância r, g e b, mas há apenas uma cópia dos campos estáticos Black, White, Red, Green e Blue:In the following example, each instance of the Color class has a separate copy of the r, g, and b instance fields, but there is only one copy of the Black, White, Red, Green, and Blue static fields:

public class Color
{
    public static readonly Color Black = new Color(0, 0, 0);
    public static readonly Color White = new Color(255, 255, 255);
    public static readonly Color Red = new Color(255, 0, 0);
    public static readonly Color Green = new Color(0, 255, 0);
    public static readonly Color Blue = new Color(0, 0, 255);
    private byte r, g, b;

    public Color(byte r, byte g, byte b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }
}

Conforme mostrado no exemplo anterior, os campos somente leitura podem ser declarados com um modificador readonly.As shown in the previous example, read-only fields may be declared with a readonly modifier. A atribuição a readonly um campo só pode ocorrer como parte da declaração do campo ou em um construtor na mesma classe.Assignment to a readonly field can only occur as part of the field's declaration or in a constructor in the same class.

MétodosMethods

Um método é um membro que implementa um cálculo ou uma ação que pode ser executada por um objeto ou classe.A method is a member that implements a computation or action that can be performed by an object or class. Os métodos estáticos são acessados pela classe.Static methods are accessed through the class. Os métodos de instância são acessados pelas instâncias da classe.Instance methods are accessed through instances of the class.

Os métodos têm uma lista de parâmetros(possivelmente vazios), que representam valores ou referências de variáveis passadas para o método, e um tipo de retorno, que especifica o tipo do valor calculado e retornado pelo método.Methods have a (possibly empty) list of parameters, which represent values or variable references passed to the method, and a return type, which specifies the type of the value computed and returned by the method. O tipo de retorno de um void método é se ele não retornar um valor.A method's return type is void if it does not return a value.

Como os tipos, os métodos também podem ter um conjunto de parâmetros de tipo, para que os quais os argumentos de tipo devem ser especificados quando o método é chamado.Like types, methods may also have a set of type parameters, for which type arguments must be specified when the method is called. Ao contrário dos tipos, os argumentos de tipo geralmente podem ser inferidos de argumentos de uma chamada de método e não precisam ser fornecidos explicitamente.Unlike types, the type arguments can often be inferred from the arguments of a method call and need not be explicitly given.

A assinatura de um método deve ser exclusiva na classe na qual o método é declarado.The signature of a method must be unique in the class in which the method is declared. A assinatura de um método consiste no nome do método, número de parâmetros de tipo e número, modificadores e tipos de seus parâmetros.The signature of a method consists of the name of the method, the number of type parameters and the number, modifiers, and types of its parameters. A assinatura de um método não inclui o tipo de retorno.The signature of a method does not include the return type.

ParâmetrosParameters

Os parâmetros são usados para passar valores ou referências de variável aos métodos.Parameters are used to pass values or variable references to methods. Os parâmetros de um método obtêm seus valores reais de argumentos que são especificados quando o método é invocado.The parameters of a method get their actual values from the arguments that are specified when the method is invoked. Há quatro tipos de parâmetros: parâmetros de valor, parâmetros de referência, parâmetros de saída e matrizes de parâmetros.There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.

Um parâmetro de valor é usado para passar o parâmetro de entrada.A value parameter is used for input parameter passing. Um parâmetro de valor corresponde a uma variável local que obtém seu valor inicial do argumento passado para o parâmetro.A value parameter corresponds to a local variable that gets its initial value from the argument that was passed for the parameter. As modificações em um parâmetro de valor não afetam o argumento passado para o parâmetro.Modifications to a value parameter do not affect the argument that was passed for the parameter.

Os parâmetros de valor podem ser opcionais, especificando um valor padrão para que os argumentos correspondentes possam ser omitidos.Value parameters can be optional, by specifying a default value so that corresponding arguments can be omitted.

Um parâmetro de referência é usado para passar os parâmetros de entrada e saída.A reference parameter is used for both input and output parameter passing. O argumento passado para um parâmetro de referência deve ser uma variável e, durante a execução do método, o parâmetro de referência representa o mesmo local de armazenamento como a variável de argumento.The argument passed for a reference parameter must be a variable, and during execution of the method, the reference parameter represents the same storage location as the argument variable. Um parâmetro de referência é declarado com o modificador ref.A reference parameter is declared with the ref modifier. O exemplo a seguir mostra o uso de parâmetros ref.The following example shows the use of ref parameters.

using System;

class Test
{
    static void Swap(ref int x, ref int y) {
        int temp = x;
        x = y;
        y = temp;
    }

    static void Main() {
        int i = 1, j = 2;
        Swap(ref i, ref j);
        Console.WriteLine("{0} {1}", i, j);            // Outputs "2 1"
    }
}

Um parâmetro de saída é usado para passar o parâmetro de entrada.An output parameter is used for output parameter passing. Um parâmetro de saída é semelhante a um parâmetro de referência, exceto que o valor inicial do argumento fornecido não é importante.An output parameter is similar to a reference parameter except that the initial value of the caller-provided argument is unimportant. Um parâmetro de saída é declarado com o modificador out.An output parameter is declared with the out modifier. O exemplo a seguir mostra o uso de parâmetros out.The following example shows the use of out parameters.

using System;

class Test
{
    static void Divide(int x, int y, out int result, out int remainder) {
        result = x / y;
        remainder = x % y;
    }

    static void Main() {
        int res, rem;
        Divide(10, 3, out res, out rem);
        Console.WriteLine("{0} {1}", res, rem);    // Outputs "3 1"
    }
}

Uma matriz de parâmetros permite que um número variável de argumentos sejam passados para um método.A parameter array permits a variable number of arguments to be passed to a method. Uma matriz de parâmetro é declarada com o modificador params.A parameter array is declared with the params modifier. Somente o último parâmetro de um método pode ser uma matriz de parâmetros e o tipo de uma matriz de parâmetros deve ser um tipo de matriz unidimensional.Only the last parameter of a method can be a parameter array, and the type of a parameter array must be a single-dimensional array type. Os Write métodos WriteLine e daSystem.Console classe são bons exemplos de uso de matriz de parâmetros.The Write and WriteLine methods of the System.Console class are good examples of parameter array usage. Eles são declarados como segue.They are declared as follows.

public class Console
{
    public static void Write(string fmt, params object[] args) {...}
    public static void WriteLine(string fmt, params object[] args) {...}
    ...
}

Dentro de um método que usa uma matriz de parâmetros, a matriz de parâmetros se comporta exatamente como um parâmetro regular de um tipo de matriz.Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. No entanto, em uma invocação de um método com uma matriz de parâmetros, é possível passar um único argumento do tipo da matriz de parâmetro ou qualquer número de argumentos do tipo de elemento da matriz de parâmetros.However, in an invocation of a method with a parameter array, it is possible to pass either a single argument of the parameter array type or any number of arguments of the element type of the parameter array. No último caso, uma instância de matriz é automaticamente criada e inicializada com os argumentos determinados.In the latter case, an array instance is automatically created and initialized with the given arguments. Esse exemploThis example

Console.WriteLine("x={0} y={1} z={2}", x, y, z);

é equivalente ao escrito a seguir.is equivalent to writing the following.

string s = "x={0} y={1} z={2}";
object[] args = new object[3];
args[0] = x;
args[1] = y;
args[2] = z;
Console.WriteLine(s, args);

Corpo do método e variáveis locaisMethod body and local variables

O corpo de um método especifica as instruções a serem executadas quando o método é invocado.A method's body specifies the statements to execute when the method is invoked.

Um corpo de método pode declarar variáveis que são específicas para a invocação do método.A method body can declare variables that are specific to the invocation of the method. Essas variáveis são chamadas de variáveis locais.Such variables are called local variables. Uma declaração de variável local especifica um nome de tipo, um nome de variável e, possivelmente, um valor inicial.A local variable declaration specifies a type name, a variable name, and possibly an initial value. O exemplo a seguir declara uma variável local i com um valor inicial de zero e uma variável local j sem valor inicial.The following example declares a local variable i with an initial value of zero and a local variable j with no initial value.

using System;

class Squares
{
    static void Main() {
        int i = 0;
        int j;
        while (i < 10) {
            j = i * i;
            Console.WriteLine("{0} x {0} = {1}", i, j);
            i = i + 1;
        }
    }
}

O C# requer que uma variável local seja atribuída definitivamente antes de seu valor poder ser obtido.C# requires a local variable to be definitely assigned before its value can be obtained. Por exemplo, se a declaração do i anterior não incluísse um valor inicial, o compilador relataria um erro para usos subsequentes de i porque i não seria definitivamente atribuído a esses pontos do programa.For example, if the declaration of the previous i did not include an initial value, the compiler would report an error for the subsequent usages of i because i would not be definitely assigned at those points in the program.

Um método pode usar instruções return para retornar o controle é pelo chamador.A method can use return statements to return control to its caller. Em um método que retorna void, as instruções return não podem especificar uma expressão.In a method returning void, return statements cannot specify an expression. Em um método que retorna instruçõesvoidnão return -, deve incluir uma expressão que computa o valor de retorno.In a method returning non-void, return statements must include an expression that computes the return value.

Métodos estáticos e de instânciaStatic and instance methods

Um método declarado com um static modificador é um método estático.A method declared with a static modifier is a static method. Um método estático não funciona em uma instância específica e pode acessar diretamente apenas membros estáticos.A static method does not operate on a specific instance and can only directly access static members.

Um método declarado sem um static modificador é um método de instância.A method declared without a static modifier is an instance method. Um método de instância opera em uma instância específica e pode acessar membros estáticos e de instância.An instance method operates on a specific instance and can access both static and instance members. A instância em que um método de instância foi invocado pode ser explicitamente acessada como this.The instance on which an instance method was invoked can be explicitly accessed as this. É um erro se referir a this em um método estático.It is an error to refer to this in a static method.

A seguinte classe Entity tem membros estáticos e de instância.The following Entity class has both static and instance members.

class Entity
{
    static int nextSerialNo;
    int serialNo;

    public Entity() {
        serialNo = nextSerialNo++;
    }

    public int GetSerialNo() {
        return serialNo;
    }

    public static int GetNextSerialNo() {
        return nextSerialNo;
    }

    public static void SetNextSerialNo(int value) {
        nextSerialNo = value;
    }
}

Cada instância Entity contém um número de série (e, possivelmente, outras informações que não são mostradas aqui).Each Entity instance contains a serial number (and presumably some other information that is not shown here). O construtor Entity (que é como um método de instância) inicializa a nova instância com o próximo número de série disponível.The Entity constructor (which is like an instance method) initializes the new instance with the next available serial number. Como o construtor é um membro de instância, ele tem permissão para acessar tanto o campo de instância serialNo e o campo estático nextSerialNo.Because the constructor is an instance member, it is permitted to access both the serialNo instance field and the nextSerialNo static field.

Os métodos estáticos GetNextSerialNo e SetNextSerialNo podem acessar o campo estático nextSerialNo, mas seria um erro para eles acessar diretamente o campo de instância serialNo.The GetNextSerialNo and SetNextSerialNo static methods can access the nextSerialNo static field, but it would be an error for them to directly access the serialNo instance field.

O exemplo a seguir mostra o uso da Entity classe.The following example shows the use of the Entity class.

using System;

class Test
{
    static void Main() {
        Entity.SetNextSerialNo(1000);
        Entity e1 = new Entity();
        Entity e2 = new Entity();
        Console.WriteLine(e1.GetSerialNo());           // Outputs "1000"
        Console.WriteLine(e2.GetSerialNo());           // Outputs "1001"
        Console.WriteLine(Entity.GetNextSerialNo());   // Outputs "1002"
    }
}

Observe que os métodos estáticos SetNextSerialNo e GetNextSerialNo são invocados na classe enquanto o método de instância GetSerialNo é chamado em instâncias da classe.Note that the SetNextSerialNo and GetNextSerialNo static methods are invoked on the class whereas the GetSerialNo instance method is invoked on instances of the class.

Métodos abstratos, virtuais e de substituiçãoVirtual, override, and abstract methods

Quando uma declaração de método de instância inclui um modificador virtual, o método deve ser um método virtual.When an instance method declaration includes a virtual modifier, the method is said to be a virtual method. Quando nenhum virtual modificador está presente, o método é considerado um método não virtual.When no virtual modifier is present, the method is said to be a non-virtual method.

Quando um método virtual é invocado, o tipo de tempo de execução da instância para o qual essa invocação ocorre determina a implementação real do método para invocar.When a virtual method is invoked, the run-time type of the instance for which that invocation takes place determines the actual method implementation to invoke. Em uma invocação de método não virtual, o tipo de tempo de compilação da instância é o fator determinante.In a nonvirtual method invocation, the compile-time type of the instance is the determining factor.

Um método virtual pode ser substituído em uma classe derivada.A virtual method can be overridden in a derived class. Quando uma declaração de método de instância override inclui um modificador, o método substitui um método virtual herdado pela mesma assinatura.When an instance method declaration includes an override modifier, the method overrides an inherited virtual method with the same signature. Enquanto uma declaração de método virtual apresenta um novo método, uma declaração de método de substituição restringe um método virtual herdado existente fornecendo uma nova implementação do método.Whereas a virtual method declaration introduces a new method, an override method declaration specializes an existing inherited virtual method by providing a new implementation of that method.

Um método abstrato é um método virtual sem implementação.An abstract method is a virtual method with no implementation. Um método abstract é declarado com o abstract modificador e é permitido somente em uma classe que também é abstractdeclarada.An abstract method is declared with the abstract modifier and is permitted only in a class that is also declared abstract. Um método abstrato deve ser substituído em cada classe derivada não abstrata.An abstract method must be overridden in every non-abstract derived class.

O exemplo a seguir declara uma classe abstrata, Expression, que representa um nó de árvore de expressão e três classes derivadas, Constant, VariableReference e Operation, que implementam nós de árvore de expressão para operações aritméticas, referências de variável e constantes.The following example declares an abstract class, Expression, which represents an expression tree node, and three derived classes, Constant, VariableReference, and Operation, which implement expression tree nodes for constants, variable references, and arithmetic operations. (Isso é semelhante a, mas não deve ser confundido com os tipos de árvore de expressão introduzidos em tipos de árvore de expressão).(This is similar to, but not to be confused with the expression tree types introduced in Expression tree types).

using System;
using System.Collections;

public abstract class Expression
{
    public abstract double Evaluate(Hashtable vars);
}

public class Constant: Expression
{
    double value;

    public Constant(double value) {
        this.value = value;
    }

    public override double Evaluate(Hashtable vars) {
        return value;
    }
}

public class VariableReference: Expression
{
    string name;

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

    public override double Evaluate(Hashtable vars) {
        object value = vars[name];
        if (value == null) {
            throw new Exception("Unknown variable: " + name);
        }
        return Convert.ToDouble(value);
    }
}

public class Operation: Expression
{
    Expression left;
    char op;
    Expression right;

    public Operation(Expression left, char op, Expression right) {
        this.left = left;
        this.op = op;
        this.right = right;
    }

    public override double Evaluate(Hashtable vars) {
        double x = left.Evaluate(vars);
        double y = right.Evaluate(vars);
        switch (op) {
            case '+': return x + y;
            case '-': return x - y;
            case '*': return x * y;
            case '/': return x / y;
        }
        throw new Exception("Unknown operator");
    }
}

As quatro classes anteriores podem ser usadas para modelar expressões aritméticas.The previous four classes can be used to model arithmetic expressions. Por exemplo, usando instâncias dessas classes, a expressão x + 3 pode ser representada da seguinte maneira.For example, using instances of these classes, the expression x + 3 can be represented as follows.

Expression e = new Operation(
    new VariableReference("x"),
    '+',
    new Constant(3));

O método Evaluate de uma instância Expression é chamado para avaliar a expressão especificada e produzir um valor double.The Evaluate method of an Expression instance is invoked to evaluate the given expression and produce a double value. O método usa como um argumento a Hashtable que contém nomes de variáveis (como chaves das entradas) e valores (como valores das entradas).The method takes as an argument a Hashtable that contains variable names (as keys of the entries) and values (as values of the entries). O Evaluate método é um método abstrato virtual, o que significa que classes derivadas não abstratas devem substituí-lo para fornecer uma implementação real.The Evaluate method is a virtual abstract method, meaning that non-abstract derived classes must override it to provide an actual implementation.

Uma implementação de Evaluate do Constant retorna apenas a constante armazenada.A Constant's implementation of Evaluate simply returns the stored constant. VariableReferenceA implementação de a pesquisa o nome da variável na tabela de hash e retorna o valor resultante.A VariableReference's implementation looks up the variable name in the hashtable and returns the resulting value. Uma implementação de Operation primeiro avalia os operandos esquerdo e direito (chamando recursivamente seus métodos Evaluate) e, em seguida, executa a operação aritmética determinada.An Operation's implementation first evaluates the left and right operands (by recursively invoking their Evaluate methods) and then performs the given arithmetic operation.

O seguinte programa usa as classes Expression para avaliar a expressão x * (y + 2) para valores diferentes de x e y.The following program uses the Expression classes to evaluate the expression x * (y + 2) for different values of x and y.

using System;
using System.Collections;

class Test
{
    static void Main() {
        Expression e = new Operation(
            new VariableReference("x"),
            '*',
            new Operation(
                new VariableReference("y"),
                '+',
                new Constant(2)
            )
        );
        Hashtable vars = new Hashtable();
        vars["x"] = 3;
        vars["y"] = 5;
        Console.WriteLine(e.Evaluate(vars));        // Outputs "21"
        vars["x"] = 1.5;
        vars["y"] = 9;
        Console.WriteLine(e.Evaluate(vars));        // Outputs "16.5"
    }
}

Sobrecarga de métodoMethod overloading

A sobrecarga de método permite que vários métodos na mesma classe tenham o mesmo nome, contanto que tenham assinaturas exclusivas.Method overloading permits multiple methods in the same class to have the same name as long as they have unique signatures. Ao compilar uma invocação de um método sobrecarregado, o compilador usa a resolução de sobrecarga para determinar o método específico para invocar.When compiling an invocation of an overloaded method, the compiler uses overload resolution to determine the specific method to invoke. A resolução de sobrecarga localizará o método que melhor corresponde aos argumentos ou relatará um erro se nenhuma correspondência for encontrada.Overload resolution finds the one method that best matches the arguments or reports an error if no single best match can be found. O exemplo a seguir mostra a resolução de sobrecarga em vigor.The following example shows overload resolution in effect. O comentário para cada invocação no método Main mostra qual método é realmente chamado.The comment for each invocation in the Main method shows which method is actually invoked.

class Test
{
    static void F() {
        Console.WriteLine("F()");
    }

    static void F(object x) {
        Console.WriteLine("F(object)");
    }

    static void F(int x) {
        Console.WriteLine("F(int)");
    }

    static void F(double x) {
        Console.WriteLine("F(double)");
    }

    static void F<T>(T x) {
        Console.WriteLine("F<T>(T)");
    }

    static void F(double x, double y) {
        Console.WriteLine("F(double, double)");
    }

    static void Main() {
        F();                 // Invokes F()
        F(1);                // Invokes F(int)
        F(1.0);              // Invokes F(double)
        F("abc");            // Invokes F(object)
        F((double)1);        // Invokes F(double)
        F((object)1);        // Invokes F(object)
        F<int>(1);           // Invokes F<T>(T)
        F(1, 1);             // Invokes F(double, double)
    }
}

Conforme mostrado no exemplo, um determinado método sempre pode ser selecionado ao converter explicitamente os argumentos para os tipos de parâmetro exatos e/ou fornecendo explicitamente os argumentos de tipo.As shown by the example, a particular method can always be selected by explicitly casting the arguments to the exact parameter types and/or explicitly supplying type arguments.

Outros membros da funçãoOther function members

Os membros que contêm código executável são conhecidos coletivamente como membros de função de uma classe.Members that contain executable code are collectively known as the function members of a class. A seção anterior descreve os métodos, que são o tipo principal de membros da função.The preceding section describes methods, which are the primary kind of function members. Esta seção descreve os outros tipos de membros de função com C#suporte do: construtores, propriedades, indexadores, eventos, operadores e destruidores.This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and destructors.

O código a seguir mostra uma classe genérica List<T>chamada, que implementa uma lista de objetos que aumenta.The following code shows a generic class called List<T>, which implements a growable list of objects. A classe contém vários exemplos dos tipos mais comuns de membros da função.The class contains several examples of the most common kinds of function members.

public class List<T> {
    // Constant...
    const int defaultCapacity = 4;

    // Fields...
    T[] items;
    int count;

    // Constructors...
    public List(int capacity = defaultCapacity) {
        items = new T[capacity];
    }

    // Properties...
    public int Count {
        get { return count; }
    }
    public int Capacity {
        get {
            return items.Length;
        }
        set {
            if (value < count) value = count;
            if (value != items.Length) {
                T[] newItems = new T[value];
                Array.Copy(items, 0, newItems, 0, count);
                items = newItems;
            }
        }
    }

    // Indexer...
    public T this[int index] {
        get {
            return items[index];
        }
        set {
            items[index] = value;
            OnChanged();
        }
    }

    // Methods...
    public void Add(T item) {
        if (count == Capacity) Capacity = count * 2;
        items[count] = item;
        count++;
        OnChanged();
    }
    protected virtual void OnChanged() {
        if (Changed != null) Changed(this, EventArgs.Empty);
    }
    public override bool Equals(object other) {
        return Equals(this, other as List<T>);
    }
    static bool Equals(List<T> a, List<T> b) {
        if (a == null) return b == null;
        if (b == null || a.count != b.count) return false;
        for (int i = 0; i < a.count; i++) {
            if (!object.Equals(a.items[i], b.items[i])) {
                return false;
            }
        }
        return true;
    }

    // Event...
    public event EventHandler Changed;

    // Operators...
    public static bool operator ==(List<T> a, List<T> b) {
        return Equals(a, b);
    }
    public static bool operator !=(List<T> a, List<T> b) {
        return !Equals(a, b);
    }
}

ConstrutoresConstructors

O C# dá suporte aos construtores estáticos e de instância.C# supports both instance and static constructors. Um construtor de instância é um membro que implementa as ações necessárias para inicializar uma instância de uma classe.An instance constructor is a member that implements the actions required to initialize an instance of a class. Um construtor estático é um membro que implementa as ações necessárias para inicializar uma classe quando ele for carregado pela primeira vez.A static constructor is a member that implements the actions required to initialize a class itself when it is first loaded.

Um construtor é declarado como um método sem nenhum tipo de retorno e o mesmo nome que a classe continente.A constructor is declared like a method with no return type and the same name as the containing class. Se uma declaração de Construtor incluir static um modificador, ele declara um construtor estático.If a constructor declaration includes a static modifier, it declares a static constructor. Caso contrário, ela declara um construtor de instância.Otherwise, it declares an instance constructor.

Construtores de instância podem ser sobrecarregados.Instance constructors can be overloaded. Por exemplo, a classe List<T> declara dois construtores de instância, um sem parâmetros e um que utiliza um parâmetro int.For example, the List<T> class declares two instance constructors, one with no parameters and one that takes an int parameter. Os construtores de instância são invocados usando o operador new.Instance constructors are invoked using the new operator. As instruções a seguir alocam duas List<string> instâncias usando cada um dos construtores List da classe.The following statements allocate two List<string> instances using each of the constructors of the List class.

List<string> list1 = new List<string>();
List<string> list2 = new List<string>(10);

Diferentemente de outros membros, construtores de instância não são herdados e uma classe não tem nenhum construtor de instância que não os que são realmente declarados na classe.Unlike other members, instance constructors are not inherited, and a class has no instance constructors other than those actually declared in the class. Se nenhum construtor de instância for fornecido para uma classe, então um construtor vazio sem parâmetros será fornecido automaticamente.If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

PropriedadesProperties

As propriedades são uma extensão natural dos campos.Properties are a natural extension of fields. Elas são denominadas membros com tipos associados, e a sintaxe para acessar os campos e as propriedades é a mesma.Both are named members with associated types, and the syntax for accessing fields and properties is the same. No entanto, diferentemente dos campos, as propriedades não denotam locais de armazenamento.However, unlike fields, properties do not denote storage locations. Em vez disso, as propriedades têm acessadores que especificam as instruções a serem executadas quando os valores forem lidos ou gravados.Instead, properties have accessors that specify the statements to be executed when their values are read or written.

Uma propriedade é declarada como um campo, exceto que a declaração termina get com um acessador set e/ou um acessador { escrito } entre os delimitadores e em vez de terminar em um ponto e vírgula.A property is declared like a field, except that the declaration ends with a get accessor and/or a set accessor written between the delimiters { and } instead of ending in a semicolon. Uma propriedade que tem get um acessador e um set acessador é uma propriedade de leitura/gravação, uma propriedade get que tem apenas um acessador é uma propriedade somente leiturae uma propriedade set que tem apenas um acessador é um propriedade somente gravação.A property that has both a get accessor and a set accessor is a read-write property, a property that has only a get accessor is a read-only property, and a property that has only a set accessor is a write-only property.

Um get acessador corresponde a um método sem parâmetros com um valor de retorno do tipo de propriedade.A get accessor corresponds to a parameterless method with a return value of the property type. Exceto como o destino de uma atribuição, quando uma propriedade é referenciada em uma expressão, get o acessador da propriedade é invocado para calcular o valor da propriedade.Except as the target of an assignment, when a property is referenced in an expression, the get accessor of the property is invoked to compute the value of the property.

Um set acessador corresponde a um método com um único value parâmetro chamado e nenhum tipo de retorno.A set accessor corresponds to a method with a single parameter named value and no return type. Quando uma propriedade é referenciada como o destino de uma atribuição ou como o operando ++ de --ou, set o acessador é invocado com um argumento que fornece o novo valor.When a property is referenced as the target of an assignment or as the operand of ++ or --, the set accessor is invoked with an argument that provides the new value.

A classe List<T> declara duas propriedades, Count e Capacity, que são somente leitura e leitura/gravação, respectivamente.The List<T> class declares two properties, Count and Capacity, which are read-only and read-write, respectively. A seguir está um exemplo de uso dessas propriedades.The following is an example of use of these properties.

List<string> names = new List<string>();
names.Capacity = 100;            // Invokes set accessor
int i = names.Count;             // Invokes get accessor
int j = names.Capacity;          // Invokes get accessor

Como nos campos e métodos, o C# dá suporte a propriedades de instância e a propriedades estáticas.Similar to fields and methods, C# supports both instance properties and static properties. As propriedades estáticas são declaradas com o static modificador e as propriedades de instância são declaradas sem ele.Static properties are declared with the static modifier, and instance properties are declared without it.

Os acessadores de uma propriedade podem ser virtuais.The accessor(s) of a property can be virtual. Quando uma declaração de propriedade inclui um modificador virtual, abstract ou override, ela se aplica aos acessadores da propriedade.When a property declaration includes a virtual, abstract, or override modifier, it applies to the accessor(s) of the property.

IndexadoresIndexers

Um indexador é um membro que permite que objetos sejam indexados da mesma forma que uma matriz.An indexer is a member that enables objects to be indexed in the same way as an array. Um indexador é declarado como uma propriedade, exceto se o nome do membro for this seguido por uma lista de parâmetros escrita entre os delimitadores [ e ].An indexer is declared like a property except that the name of the member is this followed by a parameter list written between the delimiters [ and ]. Os parâmetros estão disponíveis nos acessadores do indexador.The parameters are available in the accessor(s) of the indexer. Semelhante às propriedades, os indexadores podem ser de leitura-gravação, somente leitura e somente gravação, e os acessadores de um indexador pode ser virtuais.Similar to properties, indexers can be read-write, read-only, and write-only, and the accessor(s) of an indexer can be virtual.

A classe List declara um indexador único de leitura-gravação que usa um parâmetro int.The List class declares a single read-write indexer that takes an int parameter. O indexador possibilita indexar instâncias List com valores int.The indexer makes it possible to index List instances with int values. Por exemploFor example

List<string> names = new List<string>();
names.Add("Liz");
names.Add("Martha");
names.Add("Beth");
for (int i = 0; i < names.Count; i++) {
    string s = names[i];
    names[i] = s.ToUpper();
}

Os indexadores podem ser sobrecarregados, o que significa que uma classe pode declarar vários indexadores, desde que o número ou os tipos de seus parâmetros sejam diferentes.Indexers can be overloaded, meaning that a class can declare multiple indexers as long as the number or types of their parameters differ.

EventosEvents

Um evento é um membro que permite que uma classe ou objeto forneça notificações.An event is a member that enables a class or object to provide notifications. Um evento é declarado como um campo, exceto que a declaração inclui event uma palavra-chave e o tipo deve ser um tipo delegado.An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.

Em uma classe que declara um membro de evento, o evento se comporta exatamente como um campo de um tipo delegado (desde que o evento não seja abstrato e não declare acessadores).Within a class that declares an event member, the event behaves just like a field of a delegate type (provided the event is not abstract and does not declare accessors). O campo armazena uma referência a um delegado que representa os manipuladores de eventos que foram adicionados ao evento.The field stores a reference to a delegate that represents the event handlers that have been added to the event. Se nenhum manipulador de eventos estiver presente, o campo nullserá.If no event handles are present, the field is null.

A classe List<T> declara um membro único de evento chamado Changed, que indica que um novo item foi adicionado à lista.The List<T> class declares a single event member called Changed, which indicates that a new item has been added to the list. O Changed evento é gerado OnChanged pelo método virtual, que primeiro verifica se o evento é null (ou seja, se não há manipuladores presentes).The Changed event is raised by the OnChanged virtual method, which first checks whether the event is null (meaning that no handlers are present). A noção de gerar um evento é precisamente equivalente a invocar o delegado representado pelo evento — assim, não há constructos de linguagem especial para gerar eventos.The notion of raising an event is precisely equivalent to invoking the delegate represented by the event—thus, there are no special language constructs for raising events.

Os clientes reagem a eventos por meio de manipuladores de eventos.Clients react to events through event handlers. Os manipuladores de eventos são conectados usando o operador += e removidos usando o operador -=.Event handlers are attached using the += operator and removed using the -= operator. O exemplo a seguir anexa um manipulador de eventos para o evento Changed de um List<string>.The following example attaches an event handler to the Changed event of a List<string>.

using System;

class Test
{
    static int changeCount;

    static void ListChanged(object sender, EventArgs e) {
        changeCount++;
    }

    static void Main() {
        List<string> names = new List<string>();
        names.Changed += new EventHandler(ListChanged);
        names.Add("Liz");
        names.Add("Martha");
        names.Add("Beth");
        Console.WriteLine(changeCount);        // Outputs "3"
    }
}

Para cenários avançados nos quais o controle do armazenamento subjacente de um evento é desejado, uma declaração de evento pode fornecer explicitamente acessadores add e remove, que são um pouco semelhantes ao acessador set de uma propriedade.For advanced scenarios where control of the underlying storage of an event is desired, an event declaration can explicitly provide add and remove accessors, which are somewhat similar to the set accessor of a property.

OperadoresOperators

Um operador é um membro que define o significado da aplicação de um operador de expressão específico para instâncias de uma classe.An operator is a member that defines the meaning of applying a particular expression operator to instances of a class. Três tipos de operadores podem ser definidos: operadores unários, operadores binários e operadores de conversão.Three kinds of operators can be defined: unary operators, binary operators, and conversion operators. Todos os operadores devem ser declarados como public e static.All operators must be declared as public and static.

A classe List<T> declara dois operadores, operator== e operator!= e, portanto, dá um novo significado para as expressões que aplicam esses operadores a instâncias List.The List<T> class declares two operators, operator== and operator!=, and thus gives new meaning to expressions that apply those operators to List instances. Especificamente, os operadores definem a igualdade List<T> de duas instâncias como comparar cada um dos objetos contidos Equals usando seus métodos.Specifically, the operators define equality of two List<T> instances as comparing each of the contained objects using their Equals methods. O exemplo a seguir usa o operador == para comparar duas instâncias List<int>.The following example uses the == operator to compare two List<int> instances.

using System;

class Test
{
    static void Main() {
        List<int> a = new List<int>();
        a.Add(1);
        a.Add(2);
        List<int> b = new List<int>();
        b.Add(1);
        b.Add(2);
        Console.WriteLine(a == b);        // Outputs "True"
        b.Add(3);
        Console.WriteLine(a == b);        // Outputs "False"
    }
}

O primeiro Console.WriteLine gera True porque as duas listas contêm o mesmo número de objetos com os mesmos valores na mesma ordem.The first Console.WriteLine outputs True because the two lists contain the same number of objects with the same values in the same order. Como List<T> não definiu operator==, o primeiro Console.WriteLine geraria False porque a e b referenciam diferentes instâncias List<int>.Had List<T> not defined operator==, the first Console.WriteLine would have output False because a and b reference different List<int> instances.

DestruidoresDestructors

Um destruidor é um membro que implementa as ações necessárias para destruir uma instância de uma classe.A destructor is a member that implements the actions required to destruct an instance of a class. Os destruidores não podem ter parâmetros, eles não podem ter modificadores de acessibilidade e não podem ser invocados explicitamente.Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. O destruidor de uma instância é invocado automaticamente durante a coleta de lixo.The destructor for an instance is invoked automatically during garbage collection.

O coletor de lixo tem permissão de uma ampla latitude para decidir quando coletar objetos e executar destruidores.The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. Especificamente, o tempo das invocações do destruidor não é determinístico e os destruidores podem ser executados em qualquer thread.Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. Por esses e outros motivos, as classes devem implementar destruidores somente quando nenhuma outra solução for viável.For these and other reasons, classes should implement destructors only when no other solutions are feasible.

A instrução using fornece uma abordagem melhor para a destruição de objetos.The using statement provides a better approach to object destruction.

StructsStructs

Como classes, os structs são estruturas de dados que podem conter membros de dados e os membros da função, mas, ao contrário das classes, as estruturas são tipos de valor e não precisam de alocação de heap.Like classes, structs are data structures that can contain data members and function members, but unlike classes, structs are value types and do not require heap allocation. Uma variável de um tipo struct armazena diretamente os dados do struct, enquanto que uma variável de um tipo de classe armazena uma referência a um objeto alocado dinamicamente.A variable of a struct type directly stores the data of the struct, whereas a variable of a class type stores a reference to a dynamically allocated object. Os tipos de estrutura não dão suporte à herança especificada pelo usuário, e todos os tipos de structs são herdados implicitamente do tipo object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Os structs são particularmente úteis para estruturas de dados pequenas que têm semântica de valor.Structs are particularly useful for small data structures that have value semantics. Números complexos, pontos em um sistema de coordenadas ou pares chave-valor em um dicionário são exemplos de structs.Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. O uso de structs, em vez de classes para estruturas de dados pequenas, pode fazer uma grande diferença no número de alocações de memória que um aplicativo executa.The use of structs rather than classes for small data structures can make a large difference in the number of memory allocations an application performs. Por exemplo, o programa a seguir cria e inicializa uma matriz de 100 pontos.For example, the following program creates and initializes an array of 100 points. Com Point implementado como uma classe, 101 objetos separados são instanciados — um para a matriz e um para os elementos de 100.With Point implemented as a class, 101 separate objects are instantiated—one for the array and one each for the 100 elements.

class Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class Test
{
    static void Main() {
        Point[] points = new Point[100];
        for (int i = 0; i < 100; i++) points[i] = new Point(i, i);
    }
}

Uma alternativa é criar Point uma struct.An alternative is to make Point a struct.

struct Point
{
    public int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Agora, somente um objeto é instanciado — um para a matriz — e as instâncias Point são armazenadas em linha na matriz.Now, only one object is instantiated—the one for the array—and the Point instances are stored in-line in the array.

Construtores de struct são invocados com o operador new, mas isso não significa que a memória está sendo alocada.Struct constructors are invoked with the new operator, but that does not imply that memory is being allocated. Em vez de alocar dinamicamente um objeto e retornar uma referência a ele, um construtor de struct simplesmente retorna o valor do struct (normalmente em um local temporário na pilha), e esse valor é, então, copiado conforme necessário.Instead of dynamically allocating an object and returning a reference to it, a struct constructor simply returns the struct value itself (typically in a temporary location on the stack), and this value is then copied as necessary.

Com classes, é possível que duas variáveis referenciem o mesmo objeto e, portanto, é possível que operações em uma variável afetem o objeto referenciado por outra variável.With classes, it is possible for two variables to reference the same object and thus possible for operations on one variable to affect the object referenced by the other variable. Com structs, as variáveis têm sua própria cópia dos dados e não é possível que as operações em um afetem o outro.With structs, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other. Por exemplo, a saída produzida pelo fragmento de código a seguir depende de Point se ser uma classe ou uma estrutura.For example, the output produced by the following code fragment depends on whether Point is a class or a struct.

Point a = new Point(10, 10);
Point b = a;
a.x = 20;
Console.WriteLine(b.x);

Se Point é uma classe, a saída é 20 porque a e b faz referência ao mesmo objeto.If Point is a class, the output is 20 because a and b reference the same object. Se Point for uma struct, a saída será 10 porque a atribuição de a para b cria uma cópia do valor, e essa cópia não será afetada pela atribuição subsequente para a.x.If Point is a struct, the output is 10 because the assignment of a to b creates a copy of the value, and this copy is unaffected by the subsequent assignment to a.x.

O exemplo anterior destaca duas das limitações dos structs.The previous example highlights two of the limitations of structs. Primeiro, copiar um struct inteiro é, geralmente, menos eficiente do que copiar uma referência de objeto, então a passagem de atribuição e de valor do parâmetro pode ser mais custosa com structs que com tipos de referência.First, copying an entire struct is typically less efficient than copying an object reference, so assignment and value parameter passing can be more expensive with structs than with reference types. Segundo, com exceção para parâmetros ref e out, não é possível criar referências para structs, o que rege o uso em diversas situações.Second, except for ref and out parameters, it is not possible to create references to structs, which rules out their usage in a number of situations.

MatrizesArrays

Uma matriz é uma estrutura de dados que contém algumas variáveis acessadas por meio de índices calculados.An array is a data structure that contains a number of variables that are accessed through computed indices. As variáveis contidas em uma matriz, também chamadas de elementos da matriz, são todas do mesmo tipo, e esse tipo é chamado de tipo de elemento da matriz.The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the element type of the array.

Os tipos de matriz são tipos de referência, e a declaração de uma variável de matriz simplesmente reserva espaço para uma referência a uma instância de matriz.Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. As instâncias de matriz reais são criadas dinamicamente em tempo de execução new usando o operador.Actual array instances are created dynamically at run-time using the new operator. A new operação especifica o comprimento da nova instância de matriz, que é então corrigida para o tempo de vida da instância.The new operation specifies the length of the new array instance, which is then fixed for the lifetime of the instance. Os índices dos elementos de uma matriz variam de 0 a Length - 1.The indices of the elements of an array range from 0 to Length - 1. O operador new inicializa automaticamente os elementos de uma matriz usando o valor padrão, que, por exemplo, é zero para todos os tipos numéricos e null para todos os tipos de referência.The new operator automatically initializes the elements of an array to their default value, which, for example, is zero for all numeric types and null for all reference types.

O exemplo a seguir cria uma matriz de elementos int, inicializa a matriz e imprime o conteúdo da matriz.The following example creates an array of int elements, initializes the array, and prints out the contents of the array.

using System;

class Test
{
    static void Main() {
        int[] a = new int[10];
        for (int i = 0; i < a.Length; i++) {
            a[i] = i * i;
        }
        for (int i = 0; i < a.Length; i++) {
            Console.WriteLine("a[{0}] = {1}", i, a[i]);
        }
    }
}

Este exemplo cria e opera em uma matriz unidimensional.This example creates and operates on a single-dimensional array. O C# também oferece suporte a matrizes multidimensionais.C# also supports multi-dimensional arrays. O número de dimensões de um tipo de matriz, também conhecido como classificação do tipo de matriz, é o número um mais o número de vírgulas escrito entre os colchetes do tipo de matriz.The number of dimensions of an array type, also known as the rank of the array type, is one plus the number of commas written between the square brackets of the array type. O exemplo a seguir aloca uma matriz unidimensional, bidimensional e tridimensional.The following example allocates a one-dimensional, a two-dimensional, and a three-dimensional array.

int[] a1 = new int[10];
int[,] a2 = new int[10, 5];
int[,,] a3 = new int[10, 5, 2];

A matriz a1 contém 10 elementos, a matriz a2 contém 50 (10 × 5) elementos e a matriz a3 contém 100 (10 × 5 × 2) elementos.The a1 array contains 10 elements, the a2 array contains 50 (10 × 5) elements, and the a3 array contains 100 (10 × 5 × 2) elements.

O tipo do elemento de uma matriz pode ser qualquer tipo, incluindo um tipo de matriz.The element type of an array can be any type, including an array type. Uma matriz com elementos de um tipo de matriz é chamada às vezes de matriz denteada, pois os tamanhos das matrizes do elemento nem sempre precisam ser iguais.An array with elements of an array type is sometimes called a jagged array because the lengths of the element arrays do not all have to be the same. O exemplo a seguir aloca uma matriz de matrizes de int:The following example allocates an array of arrays of int:

int[][] a = new int[3][];
a[0] = new int[10];
a[1] = new int[5];
a[2] = new int[20];

A primeira linha cria uma matriz com três elementos, cada um do tipo int[], e cada um com um valor inicial de null.The first line creates an array with three elements, each of type int[] and each with an initial value of null. As linhas subsequentes inicializam os três elementos com referências às instâncias individuais da matriz de tamanhos variados.The subsequent lines then initialize the three elements with references to individual array instances of varying lengths.

O new operador permite que os valores iniciais dos elementos da matriz sejam especificados usando um inicializador de matriz, que é uma lista de expressões gravadas entre { os delimitadores e. }The new operator permits the initial values of the array elements to be specified using an array initializer, which is a list of expressions written between the delimiters { and }. O exemplo a seguir aloca e inicializa um int[] com três elementos.The following example allocates and initializes an int[] with three elements.

int[] a = new int[] {1, 2, 3};

Observe que o comprimento da matriz é inferido do número de expressões entre { e. }Note that the length of the array is inferred from the number of expressions between { and }. A variável local e declarações de campo podem ser reduzidas ainda mais, de modo que o tipo de matriz não precise ser redefinido.Local variable and field declarations can be shortened further such that the array type does not have to be restated.

int[] a = {1, 2, 3};

Os dois exemplos anteriores são equivalentes ao seguinte:Both of the previous examples are equivalent to the following:

int[] t = new int[3];
t[0] = 1;
t[1] = 2;
t[2] = 3;
int[] a = t;

InterfacesInterfaces

Uma interface define um contrato que pode ser implementado por classes e estruturas.An interface defines a contract that can be implemented by classes and structs. Uma interface pode conter métodos, propriedades, eventos e indexadores.An interface can contain methods, properties, events, and indexers. Uma interface não fornece implementações dos membros que define — ela simplesmente especifica os membros que devem ser fornecidos por classes ou estruturas que implementam a interface.An interface does not provide implementations of the members it defines—it merely specifies the members that must be supplied by classes or structs that implement the interface.

As interfaces podem empregar a herança múltipla.Interfaces may employ multiple inheritance. No exemplo a seguir, a interface IComboBox herda de ITextBox e IListBox.In the following example, the interface IComboBox inherits from both ITextBox and IListBox.

interface IControl
{
    void Paint();
}

interface ITextBox: IControl
{
    void SetText(string text);
}

interface IListBox: IControl
{
    void SetItems(string[] items);
}

interface IComboBox: ITextBox, IListBox {}

Classes e structs podem implementar várias interfaces.Classes and structs can implement multiple interfaces. No exemplo a seguir, a classe EditBox implementa IControl e IDataBound.In the following example, the class EditBox implements both IControl and IDataBound.

interface IDataBound
{
    void Bind(Binder b);
}

public class EditBox: IControl, IDataBound
{
    public void Paint() {...}
    public void Bind(Binder b) {...}
}

Quando uma classe ou struct implementa uma interface específica, as instâncias dessa classe ou struct podem ser convertidas implicitamente para esse tipo de interface.When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. Por exemploFor example

EditBox editBox = new EditBox();
IControl control = editBox;
IDataBound dataBound = editBox;

Em casos nos quais uma instância não é conhecida por ser estática para implementar uma interface específica, é possível usar conversões de tipo dinâmico.In cases where an instance is not statically known to implement a particular interface, dynamic type casts can be used. Por exemplo, as instruções a seguir usam conversões dinâmicas de tipo para obter IControl as IDataBound implementações de um objeto e de interface.For example, the following statements use dynamic type casts to obtain an object's IControl and IDataBound interface implementations. Como o tipo real do objeto é, EditBoxas conversões são realizadas com sucesso.Because the actual type of the object is EditBox, the casts succeed.

object obj = new EditBox();
IControl control = (IControl)obj;
IDataBound dataBound = (IDataBound)obj;

Na classe anterior EditBox , o Paint método da IControl interface e o Bind método da IDataBound interface são implementados usando public Membros.In the previous EditBox class, the Paint method from the IControl interface and the Bind method from the IDataBound interface are implemented using public members. C#também dá suporte a implementações explícitas de membros de interface, usando o que a classe publicou struct pode evitar fazer os membros.C# also supports explicit interface member implementations, using which the class or struct can avoid making the members public. Uma implementação de membro de interface explícita é escrita usando o nome do membro de interface totalmente qualificado.An explicit interface member implementation is written using the fully qualified interface member name. Por exemplo, a classe EditBox pode implementar os métodos IControl.Paint e IDataBound.Bind usando implementações de membros de interface explícita da seguinte maneira.For example, the EditBox class could implement the IControl.Paint and IDataBound.Bind methods using explicit interface member implementations as follows.

public class EditBox: IControl, IDataBound
{
    void IControl.Paint() {...}
    void IDataBound.Bind(Binder b) {...}
}

Os membros de interface explícita só podem ser acessados por meio do tipo de interface.Explicit interface members can only be accessed via the interface type. Por exemplo, a implementação de IControl.Paint fornecida pela classe Previous EditBox só pode ser invocada pela primeira vez pela EditBox conversão da referência IControl para o tipo de interface.For example, the implementation of IControl.Paint provided by the previous EditBox class can only be invoked by first converting the EditBox reference to the IControl interface type.

EditBox editBox = new EditBox();
editBox.Paint();                        // Error, no such method
IControl control = editBox;
control.Paint();                        // Ok

EnumsEnums

Um tipo enum é um tipo de valor diferente com um conjunto de constantes nomeadas.An enum type is a distinct value type with a set of named constants. O exemplo a seguir declara e usa um tipo enum chamado Color com três valores constantes, Red, Greene Blue.The following example declares and uses an enum type named Color with three constant values, Red, Green, and Blue.

using System;

enum Color
{
    Red,
    Green,
    Blue
}

class Test
{
    static void PrintColor(Color color) {
        switch (color) {
            case Color.Red:
                Console.WriteLine("Red");
                break;
            case Color.Green:
                Console.WriteLine("Green");
                break;
            case Color.Blue:
                Console.WriteLine("Blue");
                break;
            default:
                Console.WriteLine("Unknown color");
                break;
        }
    }

    static void Main() {
        Color c = Color.Red;
        PrintColor(c);
        PrintColor(Color.Blue);
    }
}

Cada tipo de enumeração tem um tipo integral correspondente chamado de tipo subjacente do tipo de enumeração.Each enum type has a corresponding integral type called the underlying type of the enum type. Um tipo de enumeração que não declara explicitamente um tipo subjacente tem um tipo subjacente de int.An enum type that does not explicitly declare an underlying type has an underlying type of int. O formato de armazenamento de um tipo de enumeração e o intervalo de valores possíveis são determinados pelo seu tipo subjacente.An enum type's storage format and range of possible values are determined by its underlying type. O conjunto de valores que um tipo de enumeração pode assumir não é limitado por seus membros enum.The set of values that an enum type can take on is not limited by its enum members. Em particular, qualquer valor do tipo subjacente de uma enumeração pode ser convertido para o tipo enum e é um valor válido distinto desse tipo enum.In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type.

O exemplo a seguir declara um tipo enum chamado Alignment com um tipo subjacente de sbyte.The following example declares an enum type named Alignment with an underlying type of sbyte.

enum Alignment: sbyte
{
    Left = -1,
    Center = 0,
    Right = 1
}

Conforme mostrado no exemplo anterior, uma declaração de membro de enumeração pode incluir uma expressão constante que especifica o valor do membro.As shown by the previous example, an enum member declaration can include a constant expression that specifies the value of the member. O valor constante para cada membro de enumeração deve estar no intervalo do tipo subjacente da enumeração.The constant value for each enum member must be in the range of the underlying type of the enum. Quando uma declaração de membro de enumeração não especifica explicitamente um valor, o membro recebe o valor zero (se for o primeiro membro no tipo enum) ou o valor do membro enum textualmente anterior mais um.When an enum member declaration does not explicitly specify a value, the member is given the value zero (if it is the first member in the enum type) or the value of the textually preceding enum member plus one.

Os valores de enumeração podem ser convertidos em valores integrais e vice-versa usando conversões de tipo.Enum values can be converted to integral values and vice versa using type casts. Por exemploFor example

int i = (int)Color.Blue;        // int i = 2;
Color c = (Color)2;             // Color c = Color.Blue;

O valor padrão de qualquer tipo de enumeração é o valor integral zero convertido para o tipo de enumeração.The default value of any enum type is the integral value zero converted to the enum type. Nos casos em que as variáveis são inicializadas automaticamente para um valor padrão, esse é o valor dado a variáveis de tipos enum.In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. Para que o valor padrão de um tipo de enumeração seja facilmente disponível, o literal 0 converte implicitamente em qualquer tipo de enumeração.In order for the default value of an enum type to be easily available, the literal 0 implicitly converts to any enum type. Dessa forma, o seguinte é permitido.Thus, the following is permitted.

Color c = 0;

DelegadosDelegates

Um delegado é um tipo que representa referências aos métodos com uma lista de parâmetros e tipo de retorno específicos.A delegate type represents references to methods with a particular parameter list and return type. Delegados possibilitam o tratamento de métodos como entidades que podem ser atribuídos a variáveis e passadas como parâmetros.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Os delegados são parecidos com o conceito de ponteiros de função em outras linguagens, mas ao contrário dos ponteiros de função, os delegados são orientados a objetos e fortemente tipados.Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

O exemplo a seguir declara e usa um tipo delegado chamado Function.The following example declares and uses a delegate type named Function.

using System;

delegate double Function(double x);

class Multiplier
{
    double factor;

    public Multiplier(double factor) {
        this.factor = factor;
    }

    public double Multiply(double x) {
        return x * factor;
    }
}

class Test
{
    static double Square(double x) {
        return x * x;
    }

    static double[] Apply(double[] a, Function f) {
        double[] result = new double[a.Length];
        for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
        return result;
    }

    static void Main() {
        double[] a = {0.0, 0.5, 1.0};
        double[] squares = Apply(a, Square);
        double[] sines = Apply(a, Math.Sin);
        Multiplier m = new Multiplier(2.0);
        double[] doubles =  Apply(a, m.Multiply);
    }
}

Uma instância do tipo delegado Function pode fazer referência a qualquer método que usa um argumento double e retorna um valor double.An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. O Apply método aplica um dado Function aos elementos de a double[], retornando um double[] com os resultados.The Apply method applies a given Function to the elements of a double[], returning a double[] with the results. No método Main, Apply é usado para aplicar três funções diferentes para um double[].In the Main method, Apply is used to apply three different functions to a double[].

Um delegado pode referenciar um método estático (como Square ou Math.Sin no exemplo anterior) ou um método de instância (como m.Multiply no exemplo anterior).A delegate can reference either a static method (such as Square or Math.Sin in the previous example) or an instance method (such as m.Multiply in the previous example). Um delegado que referencia um método de instância também referencia um objeto específico, e quando o método de instância é invocado por meio do delegado, esse objeto se torna this na invocação.A delegate that references an instance method also references a particular object, and when the instance method is invoked through the delegate, that object becomes this in the invocation.

Os delegados podem ser criados usando funções anônimas, que são "métodos embutidos" criados dinamicamente.Delegates can also be created using anonymous functions, which are "inline methods" that are created on the fly. As funções anônimas podem ver as variáveis locais dos métodos ao redor.Anonymous functions can see the local variables of the surrounding methods. Assim, o exemplo multiplicador acima pode ser escrito mais facilmente sem usar uma Multiplier classe:Thus, the multiplier example above can be written more easily without using a Multiplier class:

double[] doubles =  Apply(a, (double x) => x * 2.0);

Uma propriedade interessante e útil de um delegado é que ele não sabe ou se importa com a classe do método que referencia; o que importa é que o método referenciado tem os mesmos parâmetros e o tipo de retorno do delegado.An interesting and useful property of a delegate is that it does not know or care about the class of the method it references; all that matters is that the referenced method has the same parameters and return type as the delegate.

AtributosAttributes

Tipos, membros e outras entidades em um programa C# dão suporte a modificadores que controlam determinados aspectos de seu comportamento.Types, members, and other entities in a C# program support modifiers that control certain aspects of their behavior. Por exemplo, a acessibilidade de um método é controlada usando os modificadores public, protected, internal e private.For example, the accessibility of a method is controlled using the public, protected, internal, and private modifiers. O C# generaliza essa funcionalidade, de modo que os tipos definidos pelo usuário de informações declarativas podem ser anexados a entidades de programa e recuperados no tempo de execução.C# generalizes this capability such that user-defined types of declarative information can be attached to program entities and retrieved at run-time. Os programas especificam essas informações declarativas adicionais, definindo e usando os atributos.Programs specify this additional declarative information by defining and using attributes.

O exemplo a seguir declara um atributo HelpAttribute que pode ser colocado em entidades de programa para fornecem links para a documentação associada.The following example declares a HelpAttribute attribute that can be placed on program entities to provide links to their associated documentation.

using System;

public class HelpAttribute: Attribute
{
    string url;
    string topic;

    public HelpAttribute(string url) {
        this.url = url;
    }

    public string Url {
        get { return url; }
    }

    public string Topic {
        get { return topic; }
        set { topic = value; }
    }
}

Todas as classes de atributo derivam da System.Attribute classe base fornecida pelo .NET Framework.All attribute classes derive from the System.Attribute base class provided by the .NET Framework. Os atributos podem ser aplicados, fornecendo seu nome, junto com quaisquer argumentos, dentro dos colchetes pouco antes da declaração associada.Attributes can be applied by giving their name, along with any arguments, inside square brackets just before the associated declaration. Se o nome de um atributo terminar Attributeem, essa parte do nome poderá ser omitida quando o atributo for referenciado.If an attribute's name ends in Attribute, that part of the name can be omitted when the attribute is referenced. Por exemplo, o atributo HelpAttribute pode ser usado da seguinte maneira.For example, the HelpAttribute attribute can be used as follows.

[Help("http://msdn.microsoft.com/.../MyClass.htm")]
public class Widget
{
    [Help("http://msdn.microsoft.com/.../MyClass.htm", Topic = "Display")]
    public void Display(string text) {}
}

HelpAttribute Este exemplo anexa um Widget à classeeHelpAttribute outro ao métodonaclasse.DisplayThis example attaches a HelpAttribute to the Widget class and another HelpAttribute to the Display method in the class. Os construtores públicos de uma classe de atributo controlam as informações que devem ser fornecidas quando o atributo é anexado a uma entidade de programa.The public constructors of an attribute class control the information that must be provided when the attribute is attached to a program entity. As informações adicionais podem ser fornecidas ao referenciar propriedades públicas de leitura-gravação da classe de atributo (como a referência anterior à propriedade Topic).Additional information can be provided by referencing public read-write properties of the attribute class (such as the reference to the Topic property previously).

O exemplo a seguir mostra como as informações de atributo para uma determinada entidade de programa podem ser recuperadas em tempo de execução usando reflexão.The following example shows how attribute information for a given program entity can be retrieved at run-time using reflection.

using System;
using System.Reflection;

class Test
{
    static void ShowHelp(MemberInfo member) {
        HelpAttribute a = Attribute.GetCustomAttribute(member,
            typeof(HelpAttribute)) as HelpAttribute;
        if (a == null) {
            Console.WriteLine("No help for {0}", member);
        }
        else {
            Console.WriteLine("Help for {0}:", member);
            Console.WriteLine("  Url={0}, Topic={1}", a.Url, a.Topic);
        }
    }

    static void Main() {
        ShowHelp(typeof(Widget));
        ShowHelp(typeof(Widget).GetMethod("Display"));
    }
}

Quando um atributo específico for solicitado por meio de reflexão, o construtor para a classe de atributo será invocado com as informações fornecidas na origem do programa e a instância do atributo resultante será retornada.When a particular attribute is requested through reflection, the constructor for the attribute class is invoked with the information provided in the program source, and the resulting attribute instance is returned. Se forem fornecidas informações adicionais por meio de propriedades, essas propriedades serão definidas para os valores fornecidos antes que a instância do atributo seja retornada.If additional information was provided through properties, those properties are set to the given values before the attribute instance is returned.