Principais áreas de linguagemMajor language areas

Matrizes, coleções e LINQArrays, collections, and LINQ

O C# e o .NET fornecem muitos tipos de coleção diferentes.C# and .NET provide many different collection types. As matrizes têm a sintaxe definida pelo idioma.Arrays have syntax defined by the language. Os tipos de coleção genéricos são listados no System.Collections.Generic namespace.Generic collection types are listed in the System.Collections.Generic namespace. As coleções especializadas incluem System.Span<T> para acessar a memória contínua no registro de ativação e System.Memory<T> para acessar a memória contínua no heap gerenciado.Specialized collections include System.Span<T> for accessing continuous memory on the stack frame, and System.Memory<T> for accessing continuous memory on the managed heap. Todas as coleções, incluindo matrizes, Span<T> e Memory<T> compartilham um princípio unificado para iteração.All collections, including arrays, Span<T>, and Memory<T> share a unifying principle for iteration. Você usa a System.Collections.Generic.IEnumerable<T> interface.You use the System.Collections.Generic.IEnumerable<T> interface. Esse princípio unificado significa que qualquer um dos tipos de coleção pode ser usado com consultas LINQ ou outros algoritmos.This unifying principle means that any of the collection types can be used with LINQ queries or other algorithms. Você escreve métodos usando IEnumerable<T> e esses algoritmos funcionam com qualquer coleção.You write methods using IEnumerable<T> and those algorithms work with any collection.

MatrizesArrays

Uma matriz é uma estrutura de dados que contém um número de variáveis que são acessadas por meio de índices computados.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 do mesmo tipo.The variables contained in an array, also called the elements of the array, are all of the same type. Esse tipo é chamado de tipo de elemento da matriz.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 no tempo de execução usando o new operador.Actual array instances are created dynamically at runtime 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.

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[{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, respectivamente.The following example allocates a single-dimensional, a two-dimensional, and a three-dimensional array, respectively.

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, às vezes, é chamada de matriz denteada porque os comprimentos das matrizes de elementos nem todos precisam ser iguais.An array with elements of an array type is sometimes called a jagged array because the lengths of the element arrays don't 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. Em seguida, as linhas seguintes inicializam os três elementos com referências a instâncias de matriz individuais de comprimentos variáveis.The next 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 };

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

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

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

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

A foreach instrução pode ser usada para enumerar os elementos de qualquer coleção.The foreach statement can be used to enumerate the elements of any collection. O código a seguir enumera a matriz do exemplo anterior:The following code enumerates the array from the preceding example:

foreach (int item in a)
{
    Console.WriteLine(item);
}

A foreach instrução usa a IEnumerable<T> interface, portanto, pode funcionar com qualquer coleção.The foreach statement uses the IEnumerable<T> interface, so can work with any collection.

Interpolação de cadeia de caracteresString interpolation

A interpolação de cadeia de caracteres C# permite que você formate as cadeias definindo expressões cujos resultados são colocados em uma cadeia de caracteres de formato.C# string interpolation enables you to format strings by defining expressions whose results are placed in a format string. Por exemplo, o exemplo a seguir imprime a temperatura em um determinado dia a partir de um conjunto de dados meteorológicos:For example, the following example prints the temperature on a given day from a set of weather data:

Console.WriteLine($"The low and high temperature on {weatherData.Date:MM-DD-YYYY}");
Console.WriteLine($"    was {weatherData.LowTemp} and {weatherData.HighTemp}.");
// Output (similar to):
// The low and high temperature on 08-11-2020
//     was 5 and 30.

Uma cadeia de caracteres interpolada é declarada usando o $ token.An interpolated string is declared using the $ token. A interpolação de cadeia de caracteres avalia as expressões entre { e } , em seguida, converte o resultado em um string e substitui o texto entre colchetes pelo resultado da cadeia de caracteres da expressão.String interpolation evaluates the expressions between { and }, then converts the result to a string, and replaces the text between the brackets with the string result of the expression. O : na primeira expressão {weatherData.Date:MM-DD-YYYY} especifica a cadeia de caracteres de formato.The : in the first expression, {weatherData.Date:MM-DD-YYYY} specifies the format string. No exemplo anterior, ele especifica que a data deve ser impressa no formato "MM-DD-AAAA".In the preceding example, it specifies that the date should be printed in "MM-DD-YYYY" format.

Correspondência de padrõesPattern matching

A linguagem C# fornece expressões de correspondência de padrões para consultar o estado de um objeto e executar código com base nesse estado.The C# language provides pattern matching expressions to query the state of an object and execute code based on that state. Você pode inspecionar os tipos e os valores de propriedades e campos para determinar qual ação deve ser tomada.You can inspect types and the values of properties and fields to determine which action to take. A switch expressão é a principal expressão para correspondência de padrões.The switch expression is the primary expression for pattern matching.

Delegados e expressões lambdaDelegates and lambda expressions

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. Delegados são semelhantes ao conceito de ponteiros de função encontrados em algumas outras linguagens.Delegates are similar to the concept of function pointers found in some other languages. Diferentemente de ponteiros de função, os delegados são orientados a objeto e são de tipo seguro.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.

delegate double Function(double x);

class Multiplier
{
    double _factor;
    
    public Multiplier(double factor) => _factor = factor;
    
    public double Multiply(double x) => x * _factor;
}

class DelegateExample
{
    static double[] Apply(double[] a, Function f)
    {
        var result = new double[a.Length];
        for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
        return result;
    }
    
    public static void Main()
    {
        double[] a = { 0.0, 0.5, 1.0 };
        double[] squares = Apply(a, (x) => x * x);
        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 também podem ser criados usando funções anônimas, que são "métodos embutidos" que são criados quando declarados.Delegates can also be created using anonymous functions, which are "inline methods" that are created when declared. 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. O exemplo a seguir não cria uma classe:The following example doesn't create a class:

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

Um delegado não conhece ou se preocupa com a classe do método referenciado.A delegate doesn't know or care about the class of the method it references. Tudo o que importa é que o método referenciado tem os mesmos parâmetros e tipo de retorno como o delegado.All that matters is that the referenced method has the same parameters and return type as the delegate.

Async/Awaitasync / await

O C# dá suporte a programas assíncronos com duas palavras-chave: async e await .C# supports asynchronous programs with two keywords: async and await. Você adiciona o async modificador a uma declaração de método para declarar que o método é assíncrono.You add the async modifier to a method declaration to declare the method is asynchronous. O await operador informa ao compilador para aguardar de forma assíncrona que um resultado seja concluído.The await operator tells the compiler to asynchronously await for a result to finish. O controle é retornado para o chamador e o método retorna uma estrutura que gerencia o estado do trabalho assíncrono.Control is returned to the caller, and the method returns a structure that manages the state of the asynchronous work. A estrutura é normalmente um System.Threading.Tasks.Task<TResult> , mas pode ser qualquer tipo que ofereça suporte ao padrão de aguardador.The structure is typically a System.Threading.Tasks.Task<TResult>, but can be any type that supports the awaiter pattern. Esses recursos permitem que você escreva o código que lê como sua contraparte síncrona, mas é executado de forma assíncrona.These features enable you to write code that reads as its synchronous counterpart, but executes asynchronously. Por exemplo, o código a seguir baixa o home page do Microsoft docs:For example, the following code downloads the home page for Microsoft docs:

public async Task<int> RetrieveDocsHomePage()
{
    var client = new HttpClient();
    byte[] content = await client.GetByteArrayAsync("https://docs.microsoft.com/");

    Console.WriteLine($"{nameof(RetrieveDocsHomePage)}: Finished downloading.");
    return content.Length;
}

Este pequeno exemplo mostra os principais recursos para programação assíncrona:This small sample shows the major features for asynchronous programming:

  • A declaração do método inclui o async modificador.The method declaration includes the async modifier.
  • O corpo do método await s retorna o retorno do GetByteArrayAsync método.The body of the method awaits the return of the GetByteArrayAsync method.
  • O tipo especificado na return instrução corresponde ao argumento de tipo na Task<T> declaração do método.The type specified in the return statement matches the type argument in the Task<T> declaration for the method. (Um método que retorna Task instruções de uso return sem nenhum argumento).(A method that returns a Task would use return statements without any argument).

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 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.

public class HelpAttribute : Attribute
{
    string _url;        
    string _topic;
    
    public HelpAttribute(string url) => _url = url;

    public string Url => _url;

    public string Topic
    {
        get => _topic;
        set => _topic = value;
    }
}

Todas as classes de atributo derivam da Attribute classe base fornecida pela biblioteca .net.All attribute classes derive from the Attribute base class provided by the .NET library. 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 termina em Attribute, essa parte do nome pode ser omitida quando o atributo é 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 can be used as follows.

[Help("https://docs.microsoft.com/dotnet/csharp/tour-of-csharp/features")]
public class Widget
{
    [Help("https://docs.microsoft.com/dotnet/csharp/tour-of-csharp/features",
    Topic = "Display")]
    public void Display(string text) { }
}

Este exemplo anexa um HelpAttribute à classe Widget.This example attaches a HelpAttribute to the Widget class. Ele adiciona outro HelpAttribute ao método Display na classe.It adds 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).

Os metadados definidos por atributos podem ser lidos e manipulados em runtime usando reflexão.The metadata defined by attributes can be read and manipulated at runtime using reflection. Quando um atributo específico for solicitado usando esta técnica, 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 using this technique, 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.

O exemplo de código a seguir demonstra como obter as instâncias HelpAttribute associadas à classe Widget e seu método Display.The following code sample demonstrates how to get the HelpAttribute instances associated to the Widget class and its Display method.

Type widgetType = typeof(Widget);

object[] widgetClassAttributes = widgetType.GetCustomAttributes(typeof(HelpAttribute), false);

if (widgetClassAttributes.Length > 0)
{
    HelpAttribute attr = (HelpAttribute)widgetClassAttributes[0];
    Console.WriteLine($"Widget class help URL : {attr.Url} - Related topic : {attr.Topic}");
}

System.Reflection.MethodInfo displayMethod = widgetType.GetMethod(nameof(Widget.Display));

object[] displayMethodAttributes = displayMethod.GetCustomAttributes(typeof(HelpAttribute), false);

if (displayMethodAttributes.Length > 0)
{
    HelpAttribute attr = (HelpAttribute)displayMethodAttributes[0];
    Console.WriteLine($"Display method help URL : {attr.Url} - Related topic : {attr.Topic}");
}

Saiba maisLearn more

Você pode explorar mais sobre C# experimentando um dos nossos tutoriais.You can explore more about C# by trying one of our tutorials.