IntroduzioneIntroduction

C#, pronunciato "See Sharp", è un linguaggio di programmazione semplice, moderno, orientato a oggetti e indipendente dai tipi.C# (pronounced "See Sharp") is a simple, modern, object-oriented, and type-safe programming language. C# ha le sue radici nella famiglia di linguaggi C e risulterà immediatamente familiare ai programmatori di 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# è standardizzato di ECMA International come le ECMA-334 standard e da ISO/IEC come le ISO/IEC 23270 standard.C# is standardized by ECMA International as the ECMA-334 standard and by ISO/IEC as the ISO/IEC 23270 standard. Compilatore c# di Microsoft per .NET Framework è un'implementazione conforme della entrambi questi standard.Microsoft's C# compiler for the .NET Framework is a conforming implementation of both of these standards.

C# è un linguaggio orientato a oggetti, ma include anche il supporto per la programmazione orientata ai componenti.C# is an object-oriented language, but C# further includes support for component-oriented programming. La progettazione software contemporanea è basata in misura sempre maggiore su componenti software costituiti da pacchetti di funzionalità autonomi e autodescrittivi.Contemporary software design increasingly relies on software components in the form of self-contained and self-describing packages of functionality. L'aspetto chiave di tali componenti è che presentano un modello di programmazione con proprietà, metodi ed eventi. Presentano inoltre attributi che forniscono informazioni dichiarative sul componente. Questi componenti, infine, includono la propria documentazione.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# offre costrutti di linguaggio per supportare direttamente questi concetti, rendendo c# un linguaggio estremamente naturale in cui si desidera creare e usare i componenti software.C# provides language constructs to directly support these concepts, making C# a very natural language in which to create and use software components.

Diverse funzionalità C# offrono un valido aiuto per la creazione di applicazioni affidabili e durevoli: Operazione di Garbage collection recupera automaticamente la memoria occupata dagli oggetti inutilizzati. la gestione delle eccezioni offre un approccio strutturato ed estendibile al rilevamento degli errori e il ripristino; e il indipendente dai tipi progettazione del linguaggio rende impossibili la lettura da variabili non inizializzate, per indicizzare matrici oltre i limiti o per eseguire unchecked cast di tipo.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# presenta un sistema di tipi unificato.C# has a unified type system. Tutti i tipi C#, inclusi i tipi di primitiva quali int e double, ereditano da un unico tipo object radice.All C# types, including primitive types such as int and double, inherit from a single root object type. Di conseguenza, tutti i tipi condividono un set di operazioni comuni e i valori dei diversi tipi possono essere archiviati, trasportati e gestiti in modo coerente.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. C#, inoltre, supporta sia i tipi riferimento sia i tipi valore definiti dall'utente, consentendo l'allocazione dinamica di oggetti e l'archiviazione inline di strutture leggere.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.

Per garantire che i programmi c# e le librerie possono evolversi nel tempo, in modo compatibile, particolare attenzione è stato inserito nella controllo delle versioni nella progettazione di #.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. Molti linguaggi di programmazione prestano scarsa attenzione a questo aspetto e, di conseguenza, i programmi scritti in tali linguaggi si interrompono molto più spesso del necessario quando vengono introdotte nuove versioni delle librerie dipendenti.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. Gli aspetti di C#di progettazione che direttamente interessati dalle considerazioni sul controllo delle versioni includono distinte virtual e override modificatori, le regole per la risoluzione dell'overload di metodo e il supporto per le dichiarazioni di membro di interfaccia esplicita.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.

Il resto di questo capitolo vengono descritte le funzionalità essenziali del linguaggio c#.The rest of this chapter describes the essential features of the C# language. Anche se negli ultimi capitoli descrivono regole ed eccezioni in modo orientato ai dettagli e talvolta matematico, in questo capitolo è impegnata per maggiore chiarezza e brevità a scapito della completezza.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. Lo scopo consiste nel fornire un'introduzione al linguaggio di grado di agevolerà la scrittura dei primi programmi e la lettura di negli ultimi capitoli il lettore.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

Il programma "Hello World" viene tradizionalmente usato per presentare un linguaggio di programmazione.The "Hello, World" program is traditionally used to introduce a programming language. Di seguito è riportato il programma Hello, World in C#:Here it is in C#:

using System;

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

I file di origine C# hanno in genere l'estensione .cs.C# source files typically have the file extension .cs. Supponendo che il programma "Hello, World" sia archiviato nel file hello.cs, il programma può essere compilato con il compilatore Microsoft c# dalla riga di 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

che genera un assembly eseguibile denominato hello.exe.which produces an executable assembly named hello.exe. L'output prodotto dall'applicazione quando viene eseguito èThe output produced by this application when it is run is

Hello, World

Il programma "Hello World" inizia con una direttiva using che fa riferimento allo spazio dei nomi System.The "Hello, World" program starts with a using directive that references the System namespace. Gli spazi dei nomi consentono di organizzare i programmi e le librerie C# in modo gerarchico.Namespaces provide a hierarchical means of organizing C# programs and libraries. Gli spazi dei nomi contengono tipi e altri spazi dei nomi. Lo stazio dei nomi System, ad esempio, contiene diversi tipi, come la classe Console a cui viene fatto riferimento nel programma, e altri spazi dei nomi, come 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. Una direttiva using che fa riferimento a un determinato spazio dei nomi consente l'uso non qualificato dei tipi che sono membri di tale spazio dei nomi.A using directive that references a given namespace enables unqualified use of the types that are members of that namespace. Grazie alla direttiva using, il programma può usare Console.WriteLine come sintassi abbreviata per System.Console.WriteLine.Because of the using directive, the program can use Console.WriteLine as shorthand for System.Console.WriteLine.

La classe Hello dichiarata dal programma "Hello World" ha un solo membro, ovvero il metodo denominato Main.The Hello class declared by the "Hello, World" program has a single member, the method named Main. Il Main metodo viene dichiarato con la static modificatore.The Main method is declared with the static modifier. Mentre i metodi di istanza possono fare riferimento a una particolare istanza dell'oggetto contenitore usando la parola chiave this, i metodi statici operano senza riferimento a un determinato oggetto.While instance methods can reference a particular enclosing object instance using the keyword this, static methods operate without reference to a particular object. Per convenzione, un metodo statico denominato Main funge da punto di ingresso di un programma.By convention, a static method named Main serves as the entry point of a program.

L'output del programma viene prodotto dal metodo WriteLine della classe Console nello spazio dei nomi System.The output of the program is produced by the WriteLine method of the Console class in the System namespace. Questa classe viene fornita da librerie di classi .NET Framework, che, per impostazione predefinita, vengono fatto automaticamente riferimento il compilatore Microsoft c#.This class is provided by the .NET Framework class libraries, which, by default, are automatically referenced by the Microsoft C# compiler. Tenere presente che c# stesso non dispone di una libreria di runtime separato.Note that C# itself does not have a separate runtime library. Al contrario, .NET Framework è la libreria di runtime del linguaggio c#.Instead, the .NET Framework is the runtime library of C#.

Struttura del programmaProgram structure

I concetti organizzativi chiave di C# sono i programmi, gli spazi dei nomi, i tipi, i membri e gli assembly.The key organizational concepts in C# are programs, namespaces, types, members, and assemblies. I programmi C# sono costituiti da uno o più file di origine.C# programs consist of one or more source files. I programmi dichiarano i tipi, che contengono i membri e possono essere organizzati in spazi dei nomi.Programs declare types, which contain members and can be organized into namespaces. Le classi e le interfacce sono esempi di tipi.Classes and interfaces are examples of types. I campi, i metodi, le proprietà e gli eventi sono esempi di membri.Fields, methods, properties, and events are examples of members. Quando vengono compilati, i programmi C# vengono inseriti fisicamente in assembly.When C# programs are compiled, they are physically packaged into assemblies. Gli assembly hanno in genere l'estensione del file .exe oppure .dll, a seconda che implementino applicazioni oppure librerie.Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or libraries.

L'esempioThe 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;
            }
        }
    }
}

dichiara una classe denominata Stack in uno spazio dei nomi denominato Acme.Collections.declares a class named Stack in a namespace called Acme.Collections. Il nome completo di questa classe è Acme.Collections.Stack.The fully qualified name of this class is Acme.Collections.Stack. La classe contiene vari membri: un campo top, due metodi Push e Pop e una classe annidata Entry.The class contains several members: a field named top, two methods named Push and Pop, and a nested class named Entry. La classe Entry contiene altri tre membri: un campo next, un campo data e un costruttore.The Entry class further contains three members: a field named next, a field named data, and a constructor. Supponendo che il codice sorgente dell'esempio sia archiviato nel file acme.cs, la riga di comandoAssuming that the source code of the example is stored in the file acme.cs, the command line

csc /t:library acme.cs

compila l'esempio come libreria (codice senza un punto di ingresso Main) e genera un assembly denominato acme.dll.compiles the example as a library (code without a Main entry point) and produces an assembly named acme.dll.

Gli assembly contengono codice eseguibile sotto forma di Intermediate Language istruzioni (IL) e informazioni simboliche sotto forma di metadati.Assemblies contain executable code in the form of Intermediate Language (IL) instructions, and symbolic information in the form of metadata. Prima di essere eseguito, il codice IL presente in un assembly viene convertito automaticamente nel codice specifico del processore dal compilatore JIT (Just-In-Time) di .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.

Poiché un assembly è un'unità autodescrittiva di funzionalità contenente codice e metadati, in C# non sono necessari file di intestazione e direttive #include.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#. I membri e i tipi pubblici contenuti in un determinato assembly vengono resi disponibili in un programma C# semplicemente facendo riferimento a tale assembly durante la compilazione del programma.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. Questo programma usa ad esempio la classe Acme.Collections.Stack dell'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 il programma viene archiviato nel file test.cs, quando test.cs viene compilata, il acme.dll assembly possono farvi riferimento tramite il compilatore /r opzione: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

In questo modo verrà creato un assembly eseguibile denominato test.exe che, quando viene eseguito, genera l'output:This creates an executable assembly named test.exe, which, when run, produces the output:

100
10
1

C# consente di archiviare il testo di origine di un programma in vari file di origine.C# permits the source text of a program to be stored in several source files. Quando viene compilato un programma C# costituito da più file, tutti i file di origine vengono elaborati insieme e possono fare riferimento l'uno all'altro. A livello concettuale è come se tutti i file di origine fossero concatenati in un unico grande file prima di essere elaborati.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. Le dichiarazioni con prototipo non sono mai necessarie in C# perché, tranne che in rare eccezioni, l'ordine di dichiarazione non è significativo.Forward declarations are never needed in C# because, with very few exceptions, declaration order is insignificant. C# non limita un file di origine alla dichiarazione di un solo tipo pubblico e non richiede che il nome del file di origine corrisponda a un tipo dichiarato nel file di origine.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.

Tipi e variabiliTypes and variables

In C# esistono due generi di tipi: tipi valore e tipi riferimento.There are two kinds of types in C#: value types and reference types. Le variabili dei tipi valore contengono direttamente i propri dati, mentre le variabili dei tipi riferimento archiviano i riferimenti ai propri dati, noti come oggetti.Variables of value types directly contain their data whereas variables of reference types store references to their data, the latter being known as objects. Con i tipi riferimento, due variabili possono fare riferimento allo stesso oggetto e di conseguenza le operazioni su una delle due variabili possono influire sull'oggetto a cui fa riferimento l'altra.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. Con i tipi valore, ogni variabile ha una propria copia dei dati e non è possibile che le operazioni su una variabile influiscano sull'altra (tranne nel caso delle variabili di parametro 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#di tipi di valore sono ulteriormente suddivisi in tipi semplici, tipi enum, i tipi struct, e tipi nullable, e C#del i tipi di riferimento sono ulteriormente suddivise tipi di classe, i tipi di interfaccia, tipi matrice, e tipi delegati.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.

Nella tabella seguente offre una panoramica di C#del sistema di tipi.The following table provides an overview of C#'s type system.

CategoriaCategory DescrizioneDescription
Tipi valoreValue types Tipi sempliciSimple types Signed Integer: sbyte, short, int,longSigned integral: sbyte, short, int, long
Unsigned Integer: byte, ushort, uint,ulongUnsigned integral: byte, ushort, uint, ulong
Caratteri Unicode: charUnicode characters: char
Virgola mobile IEEE: float, doubleIEEE floating point: float, double
Decimale ad alta precisione: decimalHigh-precision decimal: decimal
Booleano: boolBoolean: bool
Tipi enumEnum types Tipi definiti dall'utente nel formato enum E {...}User-defined types of the form enum E {...}
Tipi structStruct types Tipi definiti dall'utente nel formato struct S {...}User-defined types of the form struct S {...}
Tipi nullableNullable types Estensioni di tutti gli altri tipi valore con un valore nullExtensions of all other value types with a null value
Tipi riferimentoReference types Tipi classeClass types Classe di base principale di tutti gli altri tipi: objectUltimate base class of all other types: object
Stringhe Unicode: stringUnicode strings: string
Tipi definiti dall'utente nel formato class C {...}User-defined types of the form class C {...}
Tipi interfacciaInterface types Tipi definiti dall'utente nel formato interface I {...}User-defined types of the form interface I {...}
Tipi matriceArray types Unidimensionale e multidimensionale, ad esempio int[] e int[,]Single- and multi-dimensional, for example, int[] and int[,]
Tipi delegatoDelegate types Tipi definiti dall'utente del form, ad esempio delegate int D(...)User-defined types of the form e.g. delegate int D(...)

Gli otto tipi integrali offrono supporto per i valori a 8, 16, 32 e 64 bit in formato con segno o senza segno.The eight integral types provide support for 8-bit, 16-bit, 32-bit, and 64-bit values in signed or unsigned form.

Tipi, i due mobile punto float e double, vengono rappresentati usando i formati a 32 bit e precisione singola e a 64 bit a precisione doppia IEEE 754.The two floating point types, float and double, are represented using the 32-bit single-precision and 64-bit double-precision IEEE 754 formats.

Il tipo decimal è un tipo dati a 128 bit adatto per i calcoli finanziari e monetari.The decimal type is a 128-bit data type suitable for financial and monetary calculations.

C#del bool tipo viene usato per rappresentare valori booleani, valori che possono essere true o false.C#'s bool type is used to represent boolean values—values that are either true or false.

Per l'elaborazione di caratteri e stringhe, in C# viene usata la codifica Unicode.Character and string processing in C# uses Unicode encoding. Il tipo char rappresenta un'unità di codice UTF-16, mentre il tipo string rappresenta una sequenza di unità di codice UTF-16.The char type represents a UTF-16 code unit, and the string type represents a sequence of UTF-16 code units.

La tabella seguente riepiloga C#di tipi numerici.The following table summarizes C#'s numeric types.

CategoriaCategory BITSBits TypeType Intervallo di precisioneRange/Precision
Signed IntegerSigned integral 88 sbyte -128...127-128...127
1616 short -32,768...32,767-32,768...32,767
3232 int -2,147,483,648...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
Unsigned IntegerUnsigned 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
Virgola mobileFloating point 3232 float 1,5 × 10 ^ −45 e 3,4 × 10 ^ 38, precisione di 7 cifre1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
6464 double 5,0 × 10 ^ − 324 e 1,7 × 10 ^ 308 precisione a 15 cifre5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision
DecimaleDecimal 128128 decimal 1.0 × 10 ^ 28 e 7,9 × 10 ^, 28 e precisione di 28 cifre1.0 × 10^−28 to 7.9 × 10^28, 28-digit precision

I programmi C# usano le dichiarazioni di tipo per creare nuovi tipi.C# programs use type declarations to create new types. Una dichiarazione di tipo consente di specificare il nome e i membri del nuovo tipo.A type declaration specifies the name and the members of the new type. Cinque delle C#di categorie di tipi sono definibili dall'utente: tipi, i tipi struct, tipi interfaccia, tipi enum di classi e tipi di delegati.Five of C#'s categories of types are user-definable: class types, struct types, interface types, enum types, and delegate types.

Un tipo di classe definisce una struttura di dati che contiene i membri dati (campi) e i membri di funzione (metodi, proprietà e altri).A class type defines a data structure that contains data members (fields) and function members (methods, properties, and others). I tipi classe supportano l'ereditarietà singola e il polimorfismo, meccanismi in base ai quali le classi derivate possono estendere e specializzare le classi di base.Class types support single inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Un tipo struct è simile a un tipo di classe in quanto rappresenta una struttura con membri dati e i membri di funzione.A struct type is similar to a class type in that it represents a structure with data members and function members. Tuttavia, a differenza delle classi, struct sono tipi valore e non richiedono l'allocazione di heap.However, unlike classes, structs are value types and do not require heap allocation. I tipi struct non supportano l'ereditarietà specificata dall'utente. Tutti i tipi struct ereditano implicitamente dal tipo object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

Un tipo di interfaccia definisce un contratto come un set denominato di membri funzione pubblici.An interface type defines a contract as a named set of public function members. Una classe o struct che implementa un'interfaccia deve fornire le implementazioni dei membri di funzione dell'interfaccia.A class or struct that implements an interface must provide implementations of the interface's function members. Un'interfaccia può ereditare da più interfacce di base e una classe o struct può implementare più interfacce.An interface may inherit from multiple base interfaces, and a class or struct may implement multiple interfaces.

Un tipo delegato rappresenta riferimenti ai metodi con un elenco di parametri specifico e il tipo restituito.A delegate type represents references to methods with a particular parameter list and return type. I delegati consentono di trattare i metodi come entità che è possibile assegnare a variabili e passare come parametri.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. I delegati sono simili al concetto di puntatori a funzione disponibili in altri linguaggi. A differenza dei puntatori a funzione, tuttavia, i delegati sono orientati agli oggetti e indipendenti dai tipi.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.

I tipi supportano tutti generics, in base al quale possono essere parametrizzati con altri tipi di classe, struct, interfaccia e delegato.Class, struct, interface and delegate types all support generics, whereby they can be parameterized with other types.

Un tipo di enumerazione è un tipo distinto con costanti denominate.An enum type is a distinct type with named constants. Ogni tipo di enumerazione ha un tipo sottostante, che deve essere uno degli otto tipi integrali.Every enum type has an underlying type, which must be one of the eight integral types. Il set di valori di un tipo di enumerazione è quello utilizzato per il set di valori del tipo sottostante.The set of values of an enum type is the same as the set of values of the underlying type.

C# supporta matrici unidimensionali e multidimensionali di qualsiasi tipo.C# supports single- and multi-dimensional arrays of any type. A differenza dei tipi elencati in precedenza, i tipi matrice non devono essere dichiarati prima dell'uso.Unlike the types listed above, array types do not have to be declared before they can be used. Al contrario, i tipi matrice vengono costruiti facendo seguire a un nome di tipo delle parentesi quadre.Instead, array types are constructed by following a type name with square brackets. Ad esempio, int[] è una matrice unidimensionale di int, int[,] è una matrice bidimensionale di int, e int[][] è una matrice unidimensionale di matrici unidimensionali di 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.

Tipi nullable inoltre non devono essere dichiarati prima di poter essere usati.Nullable types also do not have to be declared before they can be used. Per ogni tipo di valore non nullable T è presente un tipo nullable corrispondente T?, che può contenere un valore aggiuntivo null.For each non-nullable value type T there is a corresponding nullable type T?, which can hold an additional value null. Ad esempio, int? è un tipo che può contenere qualsiasi numero intero a 32 bit o il valore null.For instance, int? is a type that can hold any 32 bit integer or the value null.

C#del sistema di tipi è unificato in modo che un valore di qualsiasi tipo può essere considerato come un oggetto.C#'s type system is unified such that a value of any type can be treated as an object. In C# ogni tipo deriva direttamente o indirettamente dal tipo classe object e object è la classe di base principale di tutti i tipi.Every type in C# directly or indirectly derives from the object class type, and object is the ultimate base class of all types. I valori dei tipi riferimento vengono trattati come oggetti semplicemente visualizzando tali valori come tipi object.Values of reference types are treated as objects simply by viewing the values as type object. I valori dei tipi di valore vengono trattati come oggetti eseguendo boxing e unboxing operazioni.Values of value types are treated as objects by performing boxing and unboxing operations. Nell'esempio seguente un valore int viene convertito in object e quindi convertito nuovamente in 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 un valore di un tipo valore viene convertito nel tipo object, un'istanza dell'oggetto, denominata anche "box", viene allocata per contenere il valore e il valore viene copiato nel box.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. Al contrario, quando un object viene eseguito il cast di riferimento a un tipo valore, viene eseguito un controllo che l'oggetto di riferimento sia un box del tipo valore corretto e, se la verifica ha esito positivo, viene copiato il valore nella finestra di.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#unificato di tipo sistema ciò significa che i tipi di valore possono diventare oggetti "su"richiesta.C#'s unified type system effectively means that value types can become objects "on demand." Grazie all'unificazione, le librerie generiche che usano il tipo object possono essere usate con entrambi i tipi riferimento e valore.Because of the unification, general-purpose libraries that use type object can be used with both reference types and value types.

In C# sono disponibili diversi tipi di variabili, inclusi campi, elementi matrice, variabili locali e parametri.There are several kinds of variables in C#, including fields, array elements, local variables, and parameters. Le variabili rappresentano posizioni di archiviazione e ogni variabile dispone di un tipo che determina quali valori possono essere archiviati nella variabile, come illustrato nella tabella seguente.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 di variabileType of Variable Possibili contenutiPossible Contents
Tipo valore non-nullableNon-nullable value type Valore esattamente del tipo indicatoA value of that exact type
Tipo valore nullableNullable value type Un valore null o un valore esattamente del tipoA null value or a value of that exact type
object Un riferimento null, un riferimento a un oggetto di qualsiasi tipo riferimento o un riferimento a un valore boxed di qualsiasi tipo di valoreA null reference, a reference to an object of any reference type, or a reference to a boxed value of any value type
Tipo classeClass type Un riferimento null, un riferimento a un'istanza di quel tipo di classe o un riferimento a un'istanza di una classe derivata da tale tipo di 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 interfacciaInterface type Un riferimento null, un riferimento a un'istanza di un tipo di classe che implementa il tipo interfaccia o un riferimento a un valore boxed di un tipo di valore che implementa il tipo interfacciaA 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 matriceArray type Un riferimento null, un riferimento a un'istanza di quel tipo di matrice o un riferimento a un'istanza di un tipo matrice compatibileA null reference, a reference to an instance of that array type, or a reference to an instance of a compatible array type
Tipo delegatoDelegate type Un riferimento null o un riferimento a un'istanza di quel tipo di delegatoA null reference or a reference to an instance of that delegate type

EspressioniExpressions

Le espressioni sono costituite da operandi e operatori.Expressions are constructed from operands and operators. Gli operatori di un'espressione indicano le operazioni che devono essere eseguite sugli operandi.The operators of an expression indicate which operations to apply to the operands. Alcuni esempi di operatori sono +, -, *, / e new,Examples of operators include +, -, *, /, and new. mentre i valori effettivi, i campi, le variabili locali e le espressioni sono esempi di operandi.Examples of operands include literals, fields, local variables, and expressions.

Se un'espressione contiene più operatori, la precedenza degli operatori determina l'ordine in cui vengono valutati i singoli operatori.When an expression contains multiple operators, the precedence of the operators controls the order in which the individual operators are evaluated. L'espressione x + y * z, ad esempio, viene valutata come x + (y * z) poiché l'operatore * ha la precedenza sull'operatore +.For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the + operator.

La maggior parte degli operatori può esserein overload.Most operators can be overloaded. L'overload degli operatori consente di specificare implementazioni di operatori definite dall'utente per le operazioni in cui uno o entrambi gli operandi appartengono a un tipo struct o a una classe definita dall'utente.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.

La tabella seguente riepiloga C#di operatori, elenca le categorie di operatori in ordine di precedenza dalla più alta alla più bassa.The following table summarizes C#'s operators, listing the operator categories in order of precedence from highest to lowest. Gli operatori della stessa categoria hanno uguale precedenza.Operators in the same category have equal precedence.

CategoriaCategory EspressioneExpression DescrizioneDescription
PrimarioPrimary x.m Accesso ai membriMember access
x(...) Chiamata a metodi e delegatiMethod and delegate invocation
x[...] Accesso a matrici e indicizzatoriArray and indexer access
x++ Post-incrementoPost-increment
x-- Post-decrementoPost-decrement
new T(...) Creazione di oggetti e delegatiObject and delegate creation
new T(...){...} creazione di oggetti con inizializzatoreObject creation with initializer
new {...} inizializzatore di oggetti anonimoAnonymous object initializer
new T[...] creazione di matriciArray creation
typeof(T) ottiene l'oggetto System.Type per TObtain System.Type object for T
checked(x) Valutare l'espressione in un contesto controllato (checked)Evaluate expression in checked context
unchecked(x) Valutare l'espressione in un contesto non controllato (unchecked)Evaluate expression in unchecked context
default(T) ottiene un valore predefinito di tipo TObtain default value of type T
delegate {...} Funzione anonima (metodo anonimo)Anonymous function (anonymous method)
UnarioUnary +x identitàIdentity
-x NegazioneNegation
!x Negazione logicaLogical negation
~x Negazione bit per bitBitwise negation
++x Pre-incrementoPre-increment
--x Pre-decrementoPre-decrement
(T)x converte in modo esplicito x al tipo TExplicitly convert x to type T
await x attende in modo asincrono il completamento di xAsynchronously wait for x to complete
MoltiplicazioneMultiplicative x * y MoltiplicazioneMultiplication
x / y DivisioneDivision
x % y RestoRemainder
AddizioneAdditive x + y Addizione, concatenazione di stringhe, combinazione di delegatiAddition, string concatenation, delegate combination
x - y Sottrazione, rimozione di delegatiSubtraction, delegate removal
ShiftShift x << y Spostamento a sinistraShift left
x >> y Spostamento a destraShift right
Operatori relazionali e operatori di test del tipoRelational and type testing x < y Minore diLess than
x > y Maggiore diGreater than
x <= y Minore o uguale aLess than or equal
x >= y Maggiore o uguale aGreater than or equal
x is T restituisce true se x è un oggetto T, altrimenti falseReturn true if x is a T, false otherwise
x as T restituisce x tipizzato come T oppure null se x non è un oggetto TReturn x typed as T, or null if x is not a T
UguaglianzaEquality x == y UgualeEqual
x != y Non uguaglianzaNot equal
AND logicoLogical AND x & y AND Integer bit per bit, AND logico booleanoInteger bitwise AND, boolean logical AND
XOR logicoLogical XOR x ^ y XOR Integer bit per bit, XOR logico booleanoInteger bitwise XOR, boolean logical XOR
OR logicoLogical OR x | y OR Integer bit per bit, OR logico booleanoInteger bitwise OR, boolean logical OR
AND condizionaleConditional AND x && y Viene valutata y solo se x è trueEvaluates y only if x is true
OR condizionaleConditional OR x || y Viene valutata y solo se x è falseEvaluates y only if x is false
Null-coalescingNull coalescing x ?? y Viene valutata y se x viene null, a x in caso contrario,Evaluates to y if x is null, to x otherwise
CondizionaleConditional x ? y : z restituisce y se x è true, z se x è falseEvaluates y if x is true, z if x is false
Assegnazione o funzione anonimaAssignment or anonymous function x = y AssegnazioneAssignment
x op= y Assegnazione composta; gli operatori supportati sono *= /= %= += -= <<= >>= &= ^= |=Compound assignment; supported operators are *= /= %= += -= <<= >>= &= ^= |=
(T x) => y Funzione anonima (espressione lambda)Anonymous function (lambda expression)

IstruzioniStatements

Le azioni di un programma vengono espresse mediante istruzioni.The actions of a program are expressed using statements. C# supporta numerosi tipi di istruzioni, alcune delle quali sono definite in termini di istruzioni nidificate.C# supports several different kinds of statements, a number of which are defined in terms of embedded statements.

Un blocco consente di scrivere più istruzioni nei contesti in cui ne è consentita una sola.A block permits multiple statements to be written in contexts where a single statement is allowed. Un blocco è costituito da un elenco di istruzioni scritte tra i delimitatori { e }.A block consists of a list of statements written between the delimiters { and }.

Le istruzioni di dichiarazione vengono usate per dichiarare le costanti e le variabili locali.Declaration statements are used to declare local variables and constants.

Le istruzioni di espressione vengono usate per valutare le espressioni.Expression statements are used to evaluate expressions. Le espressioni che possono essere usate come istruzioni includono chiamate del metodo, dell'oggetto allocazioni usando il new operatore, le assegnazioni mediante = e operatori di assegnamento composti, operazioni di incremento e decremento in forma tramite il ++e -- operatori ed espressioni 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.

Le istruzioni di selezione vengono usate per selezionare una tra più istruzioni che è possibile eseguire sulla base del valore di alcune espressioni.Selection statements are used to select one of a number of possible statements for execution based on the value of some expression. In questo gruppo sono incluse le istruzioni if e switch.In this group are the if and switch statements.

Istruzioni di iterazione vengono utilizzati per eseguire ripetutamente un'istruzione incorporata.Iteration statements are used to repeatedly execute an embedded statement. In questo gruppo sono incluse le istruzioni while, do, for e foreach.In this group are the while, do, for, and foreach statements.

Le istruzioni di spostamento vengono usate per trasferire il controllo.Jump statements are used to transfer control. In questo gruppo sono incluse le istruzioni break, continue, goto, throw, return e yield.In this group are the break, continue, goto, throw, return, and yield statements.

L'istruzione try...catch viene usata per rilevare le eccezioni che si verificano durante l'esecuzione di un blocco, mentre l'istruzione try...finally viene usata per specificare il codice di finalizzazione che viene eseguito sempre, indipendentemente dal fatto che si sia verificata un'eccezione.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.

Il checked e unchecked istruzioni consentono di controllare il contesto per le conversioni e operazioni aritmetiche di tipo integrale di controllo dell'overflow.The checked and unchecked statements are used to control the overflow checking context for integral-type arithmetic operations and conversions.

L'istruzione lock viene usata per ottenere il blocco a esclusione reciproca per un oggetto specificato, eseguire un'istruzione e quindi rilasciare il blocco.The lock statement is used to obtain the mutual-exclusion lock for a given object, execute a statement, and then release the lock.

L'istruzione using viene usata per ottenere una risorsa, eseguire un'istruzione e quindi eliminare la risorsa.The using statement is used to obtain a resource, execute a statement, and then dispose of that resource.

Di seguito sono riportati esempi di ogni tipo di istruzioneBelow are examples of each kind of statement

Dichiarazioni di variabili localiLocal variable declarations

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

Dichiarazione di costante localeLocal constant declaration

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

Istruzione di espressioneExpression statement

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

if Istruzioneif statement

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

switch Istruzioneswitch 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;
    }
}

while Istruzionewhile statement

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

do Istruzionedo statement

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

for Istruzionefor statement

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

foreach Istruzioneforeach statement

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

break Istruzionebreak statement

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

continue Istruzionecontinue statement

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

goto Istruzionegoto statement

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

return Istruzionereturn statement

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

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

yield Istruzioneyield 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);
    }
}

throw e try istruzionithrow 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!");
    }
}

checked e unchecked istruzionichecked and unchecked statements

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

lock Istruzionelock statement

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

using Istruzioneusing statement

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

Classi e oggettiClasses and objects

Le classi sono i tipi C# più importanti.Classes are the most fundamental of C#'s types. Una classe è una struttura di dati che combina in una singola unità lo stato (campi) e le azioni (metodi e altri membri di funzione).A class is a data structure that combines state (fields) and actions (methods and other function members) in a single unit. Una classe fornisce una definizione per istanze della classe create dinamicamente, note anche come oggetti.A class provides a definition for dynamically created instances of the class, also known as objects. Le classi supportano l'ereditarietà e il polimorfismo, meccanismi in base ai quali le classi derivate possono estendere e specializzare le classi di base.Classes support inheritance and polymorphism, mechanisms whereby derived classes can extend and specialize base classes.

Le nuove classi vengono create tramite dichiarazioni di classe.New classes are created using class declarations. Una dichiarazione di classe inizia con un'intestazione che specifica gli attributi e i modificatori della classe, il nome della classe, la classe di base (se disponibile) e le interfacce implementate dalla 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. L'intestazione è seguita dal corpo della classe, costituito da un elenco di dichiarazioni di membro scritte tra i delimitatori { e }.The header is followed by the class body, which consists of a list of member declarations written between the delimiters { and }.

Di seguito è riportata una dichiarazione di una classe semplice denominata 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;
    }
}

Le istanze delle classi vengono create usando l'operatore new, che alloca memoria per una nuova istanza, richiama un costruttore per inizializzare l'istanza e restituisce un riferimento all'istanza.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. Le istruzioni seguenti creano due Point degli oggetti e archiviare i riferimenti agli oggetti in due variabili: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);

La memoria occupata da un oggetto viene recuperata automaticamente quando l'oggetto non è più in uso.The memory occupied by an object is automatically reclaimed when the object is no longer in use. In C# non è possibile, né necessario, deallocare oggetti in modo esplicito.It is neither necessary nor possible to explicitly deallocate objects in C#.

MembriMembers

I membri di una classe sono entrambi i membri statici oppure membri di istanza.The members of a class are either static members or instance members. I primi appartengono a classi, mentre i secondi appartengono a oggetti, ovvero a istanze di classi.Static members belong to classes, and instance members belong to objects (instances of classes).

Nella tabella seguente fornisce una panoramica dei tipi di membri di che una classe può contenere.The following table provides an overview of the kinds of members a class can contain.

MembroMember DescrizioneDescription
CostantiConstants Valori costanti associati alla classeConstant values associated with the class
CampiFields Variabili della classeVariables of the class
MetodiMethods Calcoli e azioni che possono essere eseguiti dalla classeComputations and actions that can be performed by the class
ProprietàProperties Azioni associate alla lettura e alla scrittura di proprietà denominate della classeActions associated with reading and writing named properties of the class
IndicizzatoriIndexers Azioni associate all'indicizzazione di istanze della classe, come una matriceActions associated with indexing instances of the class like an array
EventiEvents Notifiche che possono essere generate dalla classeNotifications that can be generated by the class
OperatoriOperators Conversioni e operatori di espressione supportati dalla classeConversions and expression operators supported by the class
CostruttoriConstructors Azioni necessarie per inizializzare istanze della classe o la classe stessaActions required to initialize instances of the class or the class itself
DistruttoriDestructors Azioni da eseguire prima che istanze della classe vengano eliminate in modo permanenteActions to perform before instances of the class are permanently discarded
TipiTypes Tipi annidati dichiarati dalla classeNested types declared by the class

AccessibilitàAccessibility

A ogni membro di una classe è associata una caratteristica di accessibilità, che controlla le aree di testo del programma in grado di accedere al membro.Each member of a class has an associated accessibility, which controls the regions of program text that are able to access the member. Esistono cinque diverse forme di accessibilità,There are five possible forms of accessibility. Questi report sono riepilogati nella tabella seguente.These are summarized in the following table.

AccessibilitàAccessibility SignificatoMeaning
public Accesso non limitatoAccess not limited
protected Accesso limitato a questa classe o alle classi derivate da questa classeAccess limited to this class or classes derived from this class
internal Accesso limitato a questo programmaAccess limited to this program
protected internal Accesso limitato a questo programma o alle classi derivate da questa classeAccess limited to this program or classes derived from this class
private Accesso limitato a questa classeAccess limited to this class

Parametri di tipoType parameters

Una definizione di classe può specificare un set di parametri di tipo se si fa seguire il nome della classe da un elenco di nomi di parametri di tipo, racchiuso tra parentesi uncinate.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. I parametri di tipo possono di essere utilizzati all'interno delle dichiarazioni di classe per definire i membri della classe.The type parameters can the be used in the body of the class declarations to define the members of the class. Nell'esempio seguente i parametri di tipo di Pair sono 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;
}

Un tipo di classe viene dichiarato per accettare parametri di tipo viene chiamato un tipo di classe generica.A class type that is declared to take type parameters is called a generic class type. Possono essere generici anche i tipi struct, interfaccia e delegato.Struct, interface and delegate types can also be generic.

Quando si usa la classe generica, è necessario specificare argomenti di tipo per ogni parametro di 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

Un tipo generico con argomenti di tipo specificato, ad esempio Pair<int,string> sopra, viene chiamato un tipo costruito.A generic type with type arguments provided, like Pair<int,string> above, is called a constructed type.

Classi di baseBase classes

Una dichiarazione di classe può specificare una classe di base se si fa seguire il nome della classe e i parametri di tipo dai due punti e dal nome della classe di 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. L'omissione della specifica della classe di base equivale alla derivazione dal tipo object.Omitting a base class specification is the same as deriving from type object. Nell'esempio seguente la classe di base di Point3D è Point e quella di 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;
    }
}

Una classe eredita i membri della relativa classe di base.A class inherits the members of its base class. L'ereditarietà prevede che una classe contenga in modo implicito tutti i membri della relativa classe base, fatta eccezione per l'istanza e i costruttori statici e i distruttori della classe di 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. Una classe derivata può aggiungere nuovi membri a quelli ereditati, ma non può rimuovere la definizione di un membro ereditato.A derived class can add new members to those it inherits, but it cannot remove the definition of an inherited member. Nell'esempio precedente Point3D eredita i campi x e y da Point e ogni istanza di Point3D contiene tre campi: 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.

Un tipo di classe viene implicitamente convertito in uno dei relativi tipi di classe di base.An implicit conversion exists from a class type to any of its base class types. Una variabile di un tipo di classe, quindi, può fare riferimento a un'istanza della classe o a un'istanza di una classe derivata.Therefore, a variable of a class type can reference an instance of that class or an instance of any derived class. Nel caso delle dichiarazioni di classe precedenti, ad esempio, una variabile di tipo Point può fare riferimento a Point o 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);

CampiFields

Un campo è una variabile che è associato a una classe o a un'istanza di una classe.A field is a variable that is associated with a class or with an instance of a class.

Un campo dichiarato con la static modificatore definisce un campo statico.A field declared with the static modifier defines a static field. che identifica esattamente una posizione di memoria.A static field identifies exactly one storage location. Indipendentemente dal numero di istanze di una classe create, esiste una sola copia di un campo statico.No matter how many instances of a class are created, there is only ever one copy of a static field.

Un campo dichiarato senza il static modificatore definisce un campo di istanza.A field declared without the static modifier defines an instance field. Ogni istanza di una classe contiene una copia separata di tutti i campi di istanza della classe.Every instance of a class contains a separate copy of all the instance fields of that class.

Nell'esempio seguente ogni istanza della classe Color include una copia distinta dei campi di istanza r, g e b, mentre esiste una sola copia dei campi statici 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;
    }
}

Come illustrato nell'esempio precedente, i campi di sola lettura possono essere dichiarati con un modificatore readonly.As shown in the previous example, read-only fields may be declared with a readonly modifier. Assegnazione a un readonly campo può verificarsi solo come parte della dichiarazione del campo o in un costruttore della stessa classe.Assignment to a readonly field can only occur as part of the field's declaration or in a constructor in the same class.

MetodiMethods

Un metodo è un membro che implementa un calcolo o un'azione che può essere eseguita da un oggetto o una classe.A method is a member that implements a computation or action that can be performed by an object or class. I metodi statici sono accessibili tramite la classe,Static methods are accessed through the class. mentre i metodi di istanza sono accessibili tramite istanze della classe.Instance methods are accessed through instances of the class.

I metodi hanno un elenco (eventualmente vuoto) di parametri, che rappresentano valori o riferimenti a variabili passati al metodo e una tipo restituito, che specifica il tipo di valore calcolato e restituito da il metodo.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. Il tipo restituito del metodo void se non viene restituito un valore.A method's return type is void if it does not return a value.

Come i tipi, anche i metodi possono avere un set di parametri di tipo per i quali è necessario specificare argomenti di tipo quando vengono chiamati.Like types, methods may also have a set of type parameters, for which type arguments must be specified when the method is called. A differenza dei tipi, gli argomenti di tipo possono essere spesso dedotti dagli argomenti di una chiamata al metodo e non devono essere assegnati in modo esplicito.Unlike types, the type arguments can often be inferred from the arguments of a method call and need not be explicitly given.

La firma di un metodo deve essere univoca nell'ambito della classe in cui viene dichiarato il metodo.The signature of a method must be unique in the class in which the method is declared. La firma di un metodo è costituita dal nome del metodo, dal numero di parametri di tipo e dal numero, dai modificatori e dai tipi dei rispettivi parametri.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. Nella firma di un metodo non è incluso il tipo restituito.The signature of a method does not include the return type.

ParametriParameters

I parametri consentono di passare ai metodi valori o riferimenti a variabili.Parameters are used to pass values or variable references to methods. I parametri di un metodo ottengono i valori effettivi dagli argomenti specificati quando viene richiamato il metodo.The parameters of a method get their actual values from the arguments that are specified when the method is invoked. Esistono quattro tipi di parametri: parametri di valore, parametri di riferimento, i parametri di output e matrici di parametri.There are four kinds of parameters: value parameters, reference parameters, output parameters, and parameter arrays.

Un parametro di valore consente di passare parametri di input.A value parameter is used for input parameter passing. Corrisponde a una variabile locale che ottiene il valore iniziale dall'argomento passato per il parametro.A value parameter corresponds to a local variable that gets its initial value from the argument that was passed for the parameter. Eventuali modifiche a un parametro di valore non interessano l'argomento passato per il parametro.Modifications to a value parameter do not affect the argument that was passed for the parameter.

I parametri di valore possono essere facoltativi specificando un valore predefinito. In questo caso gli argomenti corrispondenti possono essere omessi.Value parameters can be optional, by specifying a default value so that corresponding arguments can be omitted.

Un parametro di riferimento consente di passare parametri di input e di output.A reference parameter is used for both input and output parameter passing. L'argomento passato per un parametro di riferimento deve essere una variabile e, durante l'esecuzione del metodo, il parametro di riferimento rappresenta la stessa posizione di memoria della variabile di argomento.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. Un parametro di riferimento viene dichiarato con il modificatore ref.A reference parameter is declared with the ref modifier. Nell'esempio seguente viene illustrato l'uso di parametri 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"
    }
}

Un parametro di output consente di passare parametri di input.An output parameter is used for output parameter passing. Un parametro di output è simile a un parametro di riferimento, da cui differisce perché il valore iniziale dell'argomento fornito dal chiamante non è importante.An output parameter is similar to a reference parameter except that the initial value of the caller-provided argument is unimportant. Un parametro di output viene dichiarato con il modificatore out.An output parameter is declared with the out modifier. Nell'esempio seguente viene illustrato l'uso di parametri 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"
    }
}

Una matrice di parametri consente di passare un numero variabile di argomenti a un metodo.A parameter array permits a variable number of arguments to be passed to a method. Una matrice di parametri viene dichiarata con il modificatore params.A parameter array is declared with the params modifier. Solo l'ultimo parametro di un metodo può essere costituito da una matrice di parametri, che deve essere sempre di tipo unidimensionale.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. Il Write e WriteLine metodi del System.Console classe sono ottimi esempi di uso delle matrici di parametro.The Write and WriteLine methods of the System.Console class are good examples of parameter array usage. Vengono dichiarati come illustrato di seguito.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) {...}
    ...
}

All'interno di un metodo, una matrice di parametri si comporta esattamente come un normale parametro di tipo matrice.Within a method that uses a parameter array, the parameter array behaves exactly like a regular parameter of an array type. In una chiamata di un metodo con una matrice di parametri, tuttavia, è possibile passare un singolo argomento di tipo matrice di parametri oppure un qualsiasi numero di argomenti di tipo elemento della matrice di parametri.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. Nel secondo caso, un'istanza di matrice viene automaticamente creata e inizializzata con gli argomenti specificati.In the latter case, an array instance is automatically created and initialized with the given arguments. Questo esempioThis example

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

è equivalente alla sintassi seguente.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 del metodo e variabili localiMethod body and local variables

Corpo del metodo specifica le istruzioni da eseguire quando viene richiamato il metodo.A method's body specifies the statements to execute when the method is invoked.

Il corpo di un metodo può dichiarare variabili specifiche per la chiamata del metodo.A method body can declare variables that are specific to the invocation of the method. Queste variabili prendono il nome di variabili locali.Such variables are called local variables. Una dichiarazione di variabile locale specifica un nome di tipo, un nome di variabile e possibilmente un valore iniziale.A local variable declaration specifies a type name, a variable name, and possibly an initial value. Nell'esempio seguente viene dichiarata una variabile locale i con un valore iniziale pari a zero e una variabile locale j senza valore iniziale.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;
        }
    }
}

In C# è necessario assegnare esplicitamente una variabile locale prima di poterne ottenere il valore.C# requires a local variable to be definitely assigned before its value can be obtained. Se ad esempio nella dichiarazione della variabile locale i precedente non fosse stato incluso un valore iniziale, il compilatore avrebbe segnalato un errore ogni volta che la variabile i veniva usata, perché i non era assegnata esplicitamente in quei punti del programma.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.

Un metodo può usare istruzioni return per restituire il controllo al chiamante.A method can use return statements to return control to its caller. In un metodo che restituisce void, le istruzioni return non possono specificare un'espressione.In a method returning void, return statements cannot specify an expression. In un metodo di restituzione non -void, return l'istruzione deve includere un'espressione che calcola il valore restituito.In a method returning non-void, return statements must include an expression that computes the return value.

Metodi statici e di istanzaStatic and instance methods

Un metodo dichiarato con un static modificatore è una metodo statico.A method declared with a static modifier is a static method. Questo metodo non agisce su un'istanza specifica e può accedere direttamente solo a membri statici.A static method does not operate on a specific instance and can only directly access static members.

Un metodo dichiarato senza un static modificatore è un metodo di istanza.A method declared without a static modifier is an instance method. Questo metodo agisce su un'istanza specifica e può accedere a membri statici e di istanza.An instance method operates on a specific instance and can access both static and instance members. L'istanza in cui è stato richiamato un metodo di istanza è accessibile in modo esplicito come this.The instance on which an instance method was invoked can be explicitly accessed as this. È un errore fare riferimento a this in un metodo statico.It is an error to refer to this in a static method.

La classe Entity seguente contiene sia membri statici sia membri di istanza.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;
    }
}

Ogni istanza Entity contiene un numero di serie (e probabilmente anche altre informazioni non illustrate qui).Each Entity instance contains a serial number (and presumably some other information that is not shown here). Il costruttore Entity (simile a un metodo di istanza) inizializza la nuova istanza con il successivo numero di serie disponibile.The Entity constructor (which is like an instance method) initializes the new instance with the next available serial number. Poiché il costruttore è un membro di istanza, è consentito accedere sia al campo di istanza serialNo sia al campo statico nextSerialNo.Because the constructor is an instance member, it is permitted to access both the serialNo instance field and the nextSerialNo static field.

I metodi statici GetNextSerialNo e SetNextSerialNo possono accedere al campo statico nextSerialNo, ma si verificherebbe un errore se accedessero direttamente al campo di istanza 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.

L'esempio seguente illustra l'uso del 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"
    }
}

Osservare come, mentre i metodi statici SetNextSerialNo e GetNextSerialNo vengono richiamati sulla classe, il metodo di istanza GetSerialNo viene richiamato su istanze della 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.

Metodi virtuali, di override e astrattiVirtual, override, and abstract methods

Se una dichiarazione di metodo di istanza include un modificatore virtual, il metodo viene definito metodo virtuale.When an instance method declaration includes a virtual modifier, the method is said to be a virtual method. Se non si specifica virtual modificatore è presente, il metodo viene definito un metodo non virtuale.When no virtual modifier is present, the method is said to be a non-virtual method.

Quando viene richiamato un metodo virtuale, il tipo in fase di esecuzione dell'istanza per cui viene eseguita la chiamata determina l'implementazione effettiva del metodo da richiamare.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. In una chiamata a un metodo non virtuale, il fattore determinante è il tipo in fase di compilazione dell'istanza.In a nonvirtual method invocation, the compile-time type of the instance is the determining factor.

Un metodo virtuale può essere sottoposto a override in una classe derivata.A virtual method can be overridden in a derived class. Quando una dichiarazione di metodo di istanza include un override modificatore, il metodo esegue l'override di un metodo virtuale ereditato con la stessa firma.When an instance method declaration includes an override modifier, the method overrides an inherited virtual method with the same signature. Mentre una dichiarazione di metodo virtuale introduce un nuovo metodo, una dichiarazione di metodo di override specializza un metodo virtuale ereditato esistente specificando una nuova implementazione del metodo.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.

Un' astratta è un metodo virtuale senza implementazione.An abstract method is a virtual method with no implementation. Un metodo astratto viene dichiarato con la abstract modificatore ed è consentito solo in una classe che viene dichiarata abstract.An abstract method is declared with the abstract modifier and is permitted only in a class that is also declared abstract. Un metodo astratto deve essere sottoposto a override in ogni classe derivata non astratta.An abstract method must be overridden in every non-abstract derived class.

Nell'esempio seguente viene dichiarata una classe astratta, Expression, che rappresenta un nodo dell'albero delle espressioni, e tre classi derivate, Constant, VariableReference e Operation, che implementano i nodi dell'albero delle espressioni relativi a costanti, riferimenti a variabili e operazioni aritmetiche.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. (È simile a, ma non deve per essere confusa con i tipi di albero delle espressioni introdotta in tipi di albero delle espressioni).(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");
    }
}

Le quattro classi precedenti possono essere usate per modellare espressioni aritmetiche.The previous four classes can be used to model arithmetic expressions. Usando istanze di queste classi, l'espressione x + 3, ad esempio, può essere rappresentata come illustrato di seguito.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));

Il metodo Evaluate di un'istanza Expression viene richiamato per valutare l'espressione specificata e generare un valore double.The Evaluate method of an Expression instance is invoked to evaluate the given expression and produce a double value. Il metodo accetta come argomento un Hashtable che contiene i nomi delle variabili (come chiavi delle voci) e i valori (come valori delle voci).The method takes as an argument a Hashtable that contains variable names (as keys of the entries) and values (as values of the entries). Il Evaluate è un metodo astratto virtuale, vale a dire che le classi derivate non astratte necessario eseguirne l'override per fornire un'implementazione effettiva.The Evaluate method is a virtual abstract method, meaning that non-abstract derived classes must override it to provide an actual implementation.

L'implementazione di un valore Constant del metodo Evaluate restituisce semplicemente la costante memorizzata.A Constant's implementation of Evaluate simply returns the stored constant. Oggetto VariableReferencedell'implementazione cerca il nome della variabile nella tabella hash e restituisce il valore risultante.A VariableReference's implementation looks up the variable name in the hashtable and returns the resulting value. L'implementazione di un valore Operation valuta prima gli operandi sinistro e destro (richiamando in modo ricorsivo i metodi Evaluate) e quindi esegue l'operazione aritmetica specificata.An Operation's implementation first evaluates the left and right operands (by recursively invoking their Evaluate methods) and then performs the given arithmetic operation.

Il programma seguente usa le classi Expression per valutare l'espressione x * (y + 2) per valori diversi di 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"
    }
}

Overload di un metodoMethod overloading

L'overload di un metodo consente a più metodi della stessa classe di avere lo stesso nome, purché abbiano firme univoche.Method overloading permits multiple methods in the same class to have the same name as long as they have unique signatures. Quando si compila una chiamata di un metodo di overload, il compilatore usa la risoluzione dell'overload per determinare il metodo specifico da richiamare.When compiling an invocation of an overloaded method, the compiler uses overload resolution to determine the specific method to invoke. La risoluzione dell'overload trova il metodo che meglio corrisponde agli argomenti o segnala un errore se non riesce a trovare alcuna corrispondenza.Overload resolution finds the one method that best matches the arguments or reports an error if no single best match can be found. Nell'esempio seguente viene illustrato il funzionamento effettivo della risoluzione dell'overload.The following example shows overload resolution in effect. Il commento relativo a ogni chiamata del metodo Main mostra il metodo effettivamente richiamato.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)
    }
}

Come illustrato nell'esempio, è sempre possibile selezionare un metodo specifico eseguendo in modo esplicito il cast degli argomenti ai tipi di parametro corretti e/o specificando in modo esplicito gli argomenti di 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.

Altri membri di funzioneOther function members

I membri che contengono codice eseguibile sono noti come membri funzione di una classe.Members that contain executable code are collectively known as the function members of a class. Nella sezione precedente sono stati descritti i metodi, che costituiscono i membri di funzione principali.The preceding section describes methods, which are the primary kind of function members. In questa sezione vengono descritti altri membri di funzione supportati da c#: costruttori, proprietà, indicizzatori, eventi, operatori e i distruttori.This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and destructors.

Il codice seguente illustra una classe generica denominata List<T>, che implementa un elenco espandibile di oggetti.The following code shows a generic class called List<T>, which implements a growable list of objects. Nella classe sono contenuti alcuni esempi di membri di funzione più comuni.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);
    }
}

CostruttoriConstructors

C# supporta sia costruttori di istanza sia costruttori statici.C# supports both instance and static constructors. Un costruttore di istanza è un membro che implementa le azioni necessarie per inizializzare un'istanza di una classe,An instance constructor is a member that implements the actions required to initialize an instance of a class. mentre un costruttore statico è un membro che implementa le azioni necessarie per inizializzare una classe nel momento in cui viene caricata per la prima volta.A static constructor is a member that implements the actions required to initialize a class itself when it is first loaded.

Un costruttore viene dichiarato come un metodo, senza tipo restituito e con lo stesso nome della classe in cui è contenuto.A constructor is declared like a method with no return type and the same name as the containing class. Se una dichiarazione di costruttore include un static modificatore, dichiara un costruttore statico.If a constructor declaration includes a static modifier, it declares a static constructor. In caso contrario, dichiara un costruttore di istanza.Otherwise, it declares an instance constructor.

Costruttori di istanza possono essere sottoposti a overload.Instance constructors can be overloaded. La classe List<T>, ad esempio, dichiara due costruttori di istanza, uno senza parametri e uno che accetta un parametro int.For example, the List<T> class declares two instance constructors, one with no parameters and one that takes an int parameter. I costruttori di istanza vengono richiamati con l'operatore new.Instance constructors are invoked using the new operator. Le istruzioni seguenti allocano due List<string> istanze usando tutti i costruttori dell'ambito di List 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);

A differenza di altri membri, i costruttori di istanza non vengono ereditati e una classe non può contenere costruttori di istanza diversi da quelli effettivamente dichiarati nella 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 per una classe non è specificato alcun costruttore di istanza, ne viene automaticamente fornito uno vuoto senza parametri.If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

ProprietàProperties

Le proprietà sono una naturale estensione dei campi.Properties are a natural extension of fields. Entrambi sono membri denominati con tipi associati e la sintassi per accedere ai campi e alle proprietà è identica.Both are named members with associated types, and the syntax for accessing fields and properties is the same. A differenza dei campi, tuttavia, le proprietà non denotano posizioni di memoria,However, unlike fields, properties do not denote storage locations. ma hanno funzioni di accesso che specificano le istruzioni da eseguire nel momento in cui ne vengono letti o scritti i valori.Instead, properties have accessors that specify the statements to be executed when their values are read or written.

Una proprietà viene dichiarata come un campo, ad eccezione del fatto che la dichiarazione termina con un get funzione di accesso e/o un set funzione di accesso scritte tra i delimitatori { e } invece che terminano con un punto e virgola.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. Una proprietà che dispone di entrambe un get funzione di accesso e un set funzione di accesso è un proprietà di lettura / scrittura, una proprietà è disponibile solo un get funzione di accesso è un proprietà di sola letturae un proprietà che è presente solo una set funzione di accesso è un proprietà di sola scrittura.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.

Oggetto get della funzione di accesso corrispondente a un metodo senza parametri con un valore restituito del tipo di proprietà.A get accessor corresponds to a parameterless method with a return value of the property type. Fatta eccezione per quanto la destinazione di un'assegnazione, quando viene fatto riferimento a una proprietà in un'espressione, il get della funzione di accesso della proprietà viene richiamata per calcolare il valore della proprietà.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.

Oggetto set funzione di accesso corrisponde a un metodo con un singolo parametro denominato value e senza tipo restituito.A set accessor corresponds to a method with a single parameter named value and no return type. Se si fa riferimento a una proprietà come destinazione di un'assegnazione o come operando del ++ oppure --, il set della funzione di accesso viene richiamato con un argomento che fornisce il nuovo valore.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.

La classe List<T> dichiara due proprietà, Count e Capacity, che sono rispettivamente di sola lettura e di lettura/scrittura.The List<T> class declares two properties, Count and Capacity, which are read-only and read-write, respectively. Di seguito è riportato un esempio d'uso di queste proprietà.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

Come per i campi e i metodi, C# supporta sia proprietà di istanza sia proprietà statiche.Similar to fields and methods, C# supports both instance properties and static properties. Proprietà statiche vengono dichiarate con la static modificatore e le proprietà dell'istanza vengono dichiarate senza di essa.Static properties are declared with the static modifier, and instance properties are declared without it.

Le funzioni di accesso di una proprietà possono essere virtuali.The accessor(s) of a property can be virtual. Se una dichiarazione di proprietà contiene un modificatore virtual, abstract o override, questo viene applicato anche alle funzioni di accesso della proprietà.When a property declaration includes a virtual, abstract, or override modifier, it applies to the accessor(s) of the property.

IndicizzatoriIndexers

Un indicizzatore è un membro che consente di indicizzare gli oggetti esattamente come una matrice.An indexer is a member that enables objects to be indexed in the same way as an array. Un indicizzatore viene dichiarato come una proprietà, ad eccezione del fatto che il nome del membro this seguita da un elenco di parametri scritto tra i delimitatori [ 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 ]. I parametri sono disponibili nelle funzioni di accesso dell'indicizzatore.The parameters are available in the accessor(s) of the indexer. Analogamente alle proprietà, gli indicizzatori possono essere di lettura/scrittura, di sola lettura o di sola scrittura e le funzioni di accesso di un indicizzatore possono essere virtuali.Similar to properties, indexers can be read-write, read-only, and write-only, and the accessor(s) of an indexer can be virtual.

La classe List dichiara un indicizzatore di lettura/scrittura che accetta un parametro intThe List class declares a single read-write indexer that takes an int parameter. e consente di indicizzare istanze List con valori int.The indexer makes it possible to index List instances with int values. Esempio:For 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();
}

Gli indicizzatori possono essere sottoposti a overload, ovvero una classe può dichiarare più indicizzatori purché includano un numero o tipi diversi di parametri.Indexers can be overloaded, meaning that a class can declare multiple indexers as long as the number or types of their parameters differ.

EventiEvents

Un evento è un membro che consente a una classe o a un oggetto di inviare notifiche.An event is a member that enables a class or object to provide notifications. Un evento viene dichiarato come un campo, ad eccezione del fatto che la dichiarazione include un event (parola chiave) e il tipo deve essere un tipo delegato.An event is declared like a field except that the declaration includes an event keyword and the type must be a delegate type.

In una classe che dichiara un membro di evento, l'evento si comporta esattamente come un campo di un tipo delegato, purché l'evento non sia astratto e non dichiari funzioni di accesso.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). Il campo archivia un riferimento a un delegato che rappresenta i gestori eventi aggiunti all'evento.The field stores a reference to a delegate that represents the event handlers that have been added to the event. Se non sono presente alcun gestore eventi, il campo è null.If no event handles are present, the field is null.

La classe List<T> dichiara un singolo membro di evento denominato Changed, con cui si indica che un nuovo elemento è stato aggiunto all'elenco.The List<T> class declares a single event member called Changed, which indicates that a new item has been added to the list. Il Changed evento viene generato mediante il OnChanged metodo virtuale, che prima controlla se l'evento è null (vale a dire che è presente alcun gestore).The Changed event is raised by the OnChanged virtual method, which first checks whether the event is null (meaning that no handlers are present). Generare un evento equivale a richiamare il delegato rappresentato dall'evento. Non sono quindi necessari speciali costrutti di linguaggio per generare eventi.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.

I client rispondono agli eventi tramite gestori eventi,Clients react to events through event handlers. che possono essere aggiunti con l'operatore += e rimossi con l'operatore -=.Event handlers are attached using the += operator and removed using the -= operator. Nell'esempio seguente un gestore eventi viene aggiunto all'evento Changed di 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"
    }
}

Negli scenari avanzati in cui è auspicabile controllare l'archiviazione sottostante di un evento, una dichiarazione di evento può fornire in modo esplicito le funzioni di accesso add e remove, simili alla funzione di accesso set di una proprietà.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.

OperatoriOperators

Un operatore è un membro che definisce il significato dell'applicazione di un particolare operatore di espressione alle istanze di una classe.An operator is a member that defines the meaning of applying a particular expression operator to instances of a class. È possibile definire tre tipi di operatori: unari, binari e di conversione.Three kinds of operators can be defined: unary operators, binary operators, and conversion operators. Tutti gli operatori devono essere dichiarati come public e static.All operators must be declared as public and static.

La classe List<T> dichiara due operatori, operator== e operator!=, attribuendo così un nuovo significato alle espressioni che applicano questi operatori alle istanze di 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. In particolare, gli operatori definiscono l'uguaglianza di due List<T> istanze, confrontando ognuno degli oggetti contenuti con loro Equals metodi.Specifically, the operators define equality of two List<T> instances as comparing each of the contained objects using their Equals methods. Nell'esempio seguente viene usato l'operatore == per confrontare due istanze di 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"
    }
}

Il primo Console.WriteLine restituisce True perché i due elenchi contengono lo stesso numero di oggetti con gli stessi valori e nello stesso ordine.The first Console.WriteLine outputs True because the two lists contain the same number of objects with the same values in the same order. Se in List<T> non fosse stato definito l'operatore operator==, il primo Console.WriteLine avrebbe restituito False perché a e b fanno riferimento a istanze di List<int> diverse.Had List<T> not defined operator==, the first Console.WriteLine would have output False because a and b reference different List<int> instances.

DistruttoriDestructors

Oggetto distruttore è un membro che implementa le azioni necessarie per distruggere un'istanza di una classe.A destructor is a member that implements the actions required to destruct an instance of a class. I distruttori non possono avere parametri e non possono avere modificatori di accessibilità non possono essere richiamati in modo esplicito.Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. Il distruttore per un'istanza viene richiamato automaticamente durante l'operazione di garbage collection.The destructor for an instance is invoked automatically during garbage collection.

Il garbage collector viene lasciato ampia scelta per decidere quando raccogliere oggetti ed eseguire i distruttori.The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. In particolare, i tempi delle chiamate di distruttore non sono deterministico e i distruttori possono essere eseguiti in qualsiasi thread.Specifically, the timing of destructor invocations is not deterministic, and destructors may be executed on any thread. Per questi e altri motivi, le classi devono implementare i distruttori solo quando nessun altro soluzioni sono applicabili.For these and other reasons, classes should implement destructors only when no other solutions are feasible.

L'istruzione using offre una soluzione più efficace per l'eliminazione di oggetti.The using statement provides a better approach to object destruction.

StructStructs

Analogamente alle classi, i tipi struct sono strutture dati che possono contenere membri dati e membri funzione. A differenza delle classi, tuttavia, i tipi struct sono tipi valore e non richiedono l'allocazione dell'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. Una variabile di un tipo struct archivia direttamente i relativi dati, mentre una variabile di un tipo classe archivia un riferimento a un oggetto allocato in modo dinamico.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. I tipi struct non supportano l'ereditarietà specificata dall'utente. Tutti i tipi struct ereditano implicitamente dal tipo object.Struct types do not support user-specified inheritance, and all struct types implicitly inherit from type object.

I tipi struct sono particolarmente utili per strutture dati di piccole dimensioni che hanno una semantica di valori.Structs are particularly useful for small data structures that have value semantics. I numeri complessi, i punti di un sistema di coordinate o le coppie chiave-valore di un dizionario sono buoni esempi di struct.Complex numbers, points in a coordinate system, or key-value pairs in a dictionary are all good examples of structs. L'uso dei tipi struct al posto delle classi può determinare una notevole differenza riguardo al numero di allocazioni di memoria eseguite da un'applicazione.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. Il programma seguente, ad esempio, crea e inizializza una matrice di 100 punti.For example, the following program creates and initializes an array of 100 points. Con Point implementato come classe, vengono create istanze di 101 oggetti separati, uno per la matrice e uno per ciascuno dei 100 elementi.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);
    }
}

In alternativa è possibile rendere Point uno 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;
    }
}

Viene ora creata un'istanza di un solo oggetto, quello relativo alla matrice, e le istanze di Point vengono memorizzate inline nella matrice.Now, only one object is instantiated—the one for the array—and the Point instances are stored in-line in the array.

Con l'operatore new vengono chiamati i costruttori di struct, ma questo non implica l'allocazione di memoria.Struct constructors are invoked with the new operator, but that does not imply that memory is being allocated. Anziché allocare dinamicamente un oggetto e restituire un riferimento a quest'ultimo, un costruttore di struct restituisce semplicemente il valore del tipo struct (in genere una posizione temporanea nello stack), che viene quindi copiato in base alle esigenze.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.

Con le classi, due variabili possono fare riferimento allo stesso oggetto e pertanto le operazioni su una variabile possono influire sull'oggetto a cui fa riferimento l'altra.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. Con i tipi struct, ogni variabile ha una propria copia dei dati e le operazioni su una variabile non possono influire sull'altra.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. Ad esempio, l'output prodotto dal frammento di codice seguente dipende dal fatto che Point è una classe o uno struct.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 è una classe, l'output viene 20 poiché a e b fanno riferimento allo stesso oggetto.If Point is a class, the output is 20 because a and b reference the same object. Se Point è uno struct, l'output viene 10 perché l'assegnazione dei a al b crea una copia del valore, e questa copia non è interessata dalla successiva assegnazione a 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.

L'esempio precedente evidenzia due delle limitazioni dei tipi struct.The previous example highlights two of the limitations of structs. In primo luogo, la copia di un intero tipo struct è in genere meno efficiente della copia di un riferimento all'oggetto. Di conseguenza, il passaggio dei parametri di assegnazione e valore può risultare molto più costoso con i tipi struct che con i tipi riferimento.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. In secondo luogo, ad eccezione dei parametri ref e out, non è possibile creare riferimenti ai tipi struct e questa condizione che ne limita l'uso in varie situazioni.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.

MatriciArrays

Una matrice è una struttura di dati contenente una serie di variabili accessibili tramite indici calcolati.An array is a data structure that contains a number of variables that are accessed through computed indices. Le variabili contenute in una matrice, chiamate anche elementi della matrice, sono tutte dello stesso tipo, definito tipo di elemento della matrice.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.

Poiché i tipi di matrice sono tipi di riferimento, la dichiarazione di una variabile di matrice si limita a riservare spazio per un riferimento a un'istanza di matrice.Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. Istanze di matrice effettive vengono create dinamicamente in fase di esecuzione utilizzando il new operatore.Actual array instances are created dynamically at run-time using the new operator. Il new operazione consente di specificare il lunghezza della nuova istanza di matrice, che viene fissata per la durata dell'istanza.The new operation specifies the length of the new array instance, which is then fixed for the lifetime of the instance. Gli indici degli elementi di una matrice sono compresi tra 0 e Length - 1.The indices of the elements of an array range from 0 to Length - 1. L'operatore new inizializza automaticamente gli elementi di una matrice sul rispettivo valore predefinito che, ad esempio, equivale a zero per tutti i tipi numerici e a null per tutti i tipi di riferimento.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.

Nell'esempio seguente viene creata una matrice di elementi int, viene inizializzata la matrice e ne viene stampato il contenuto.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]);
        }
    }
}

In questo esempio viene creata e usata una matrice unidimensionale.This example creates and operates on a single-dimensional array. C# supporta anche matrici multidimensionali.C# also supports multi-dimensional arrays. Il numero di dimensioni di un tipo di matrice, chiamato anche rango del tipo di matrice, è pari a uno più il numero di virgole tra parentesi quadre del tipo di matrice.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. Nell'esempio seguente consente di allocare una matrice unidimensionale, una bidimensionale e una matrice tridimensionale.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];

La matrice a1 contiene 10 elementi, la matrice a2 contiene 50 (10 × 5) elementi e la a3 matrice contiene 100 (10 × 5 × 2) elementi.The a1 array contains 10 elements, the a2 array contains 50 (10 × 5) elements, and the a3 array contains 100 (10 × 5 × 2) elements.

L'elemento di una matrice può essere di qualsiasi tipo, anche di tipo matrice.The element type of an array can be any type, including an array type. Una matrice con elementi di tipo matrice viene chiamata talvolta matrice di matrici, poiché le lunghezze delle matrici elemento non devono essere tutte uguali.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. Nell'esempio seguente viene allocata una matrice di matrici di 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];

La prima riga crea una matrice con tre elementi, ognuno di tipo int[] e con un valore iniziale di null.The first line creates an array with three elements, each of type int[] and each with an initial value of null. Le righe successive inizializzano quindi i tre elementi con riferimenti a singole istanze di matrice di lunghezza variabile.The subsequent lines then initialize the three elements with references to individual array instances of varying lengths.

Il new operatore consente di specificare i valori iniziali degli elementi della matrice essere specificata tramite un inizializzatore di matrice, ovvero un elenco di espressioni scritte tra i delimitatori { 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 }. Nell'esempio seguente viene allocata e inizializzata una matrice int[] con tre elementi.The following example allocates and initializes an int[] with three elements.

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

Si noti che la lunghezza della matrice viene dedotta dal numero di espressioni tra { e }.Note that the length of the array is inferred from the number of expressions between { and }. Per evitare di ridefinire il tipo di matrice, è possibile abbreviare le dichiarazioni di campo e variabile locale.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};

Entrambi gli esempi precedenti equivalgono a quello seguente: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;

InterfacceInterfaces

Un'interfaccia definisce un contratto che può essere implementato da classi e struct.An interface defines a contract that can be implemented by classes and structs. Può contenere metodi, proprietà, eventi e indicizzatori.An interface can contain methods, properties, events, and indexers. Un'interfaccia non fornisce le implementazioni dei membri che definisce, ma specifica semplicemente i membri che devono essere forniti dalle classi o dai tipi struct che la implementano.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.

Le interfacce possono usare l'ereditarietà multipla.Interfaces may employ multiple inheritance. Nell'esempio seguente l'interfaccia IComboBox eredita da 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 {}

Classi e struct possono implementare più interfacce.Classes and structs can implement multiple interfaces. Nell'esempio seguente la 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 una classe o un tipo struct implementa un'interfaccia specifica, le istanze di tale classe o struct possono essere convertite in modo implicito in quel tipo di interfaccia.When a class or struct implements a particular interface, instances of that class or struct can be implicitly converted to that interface type. Esempio:For example

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

Nei casi in cui un'istanza non implementa staticamente un'interfaccia specifica è possibile usare cast di tipo dinamico.In cases where an instance is not statically known to implement a particular interface, dynamic type casts can be used. Ad esempio, le istruzioni seguenti usano cast di tipo dinamico per ottenere un oggetto IControl e IDataBound implementazioni di interfacce.For example, the following statements use dynamic type casts to obtain an object's IControl and IDataBound interface implementations. Poiché il tipo effettivo dell'oggetto è EditBox, i cast vengono eseguiti correttamente.Because the actual type of the object is EditBox, the casts succeed.

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

Nella precedente EditBox (classe), il Paint metodo dal IControl interfaccia e il Bind metodo dal IDataBound interfaccia vengono implementate usando public membri.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# supporta anche tali implementazioni, con cui la classe o struct può evitare di specificare i membri public.C# also supports explicit interface member implementations, using which the class or struct can avoid making the members public. Un'implementazione esplicita di un membro dell'interfaccia viene scritta usando il nome completo del membro dell'interfaccia.An explicit interface member implementation is written using the fully qualified interface member name. La classe EditBox può ad esempio implementare i metodi IControl.Paint e IDataBound.Bind usando implementazioni esplicite di un membro dell'interfaccia, come indicato di seguito.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) {...}
}

È possibile accedere ai membri dell'interfaccia esplicita solo tramite il tipo di interfaccia.Explicit interface members can only be accessed via the interface type. Ad esempio, l'implementazione di IControl.Paint fornite dalla precedente EditBox classe può essere richiamata solo convertendo per prima cosa il EditBox fanno riferimento al IControl tipo interfaccia.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

EnumerazioniEnums

Un tipo enum è un tipo valore distinto con un set di costanti denominate.An enum type is a distinct value type with a set of named constants. Nell'esempio seguente viene dichiarato e usato un tipo di enumerazione denominato Color con tre valori di costante Red, Green, e 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);
    }
}

Ogni tipo di enumerazione ha un tipo integrale corrispondente denominato il tipo sottostante del tipo di enumerazione.Each enum type has a corresponding integral type called the underlying type of the enum type. Un tipo di enumerazione che non dichiara in modo esplicito un tipo sottostante è un tipo sottostante di int.An enum type that does not explicitly declare an underlying type has an underlying type of int. Il formato di archiviazione e l'intervallo di valori possibili sono determinati dal tipo sottostante.An enum type's storage format and range of possible values are determined by its underlying type. Il set di valori che può assumere un tipo enum non è limitato dai relativi membri enum.The set of values that an enum type can take on is not limited by its enum members. In particolare, qualsiasi valore del tipo sottostante di un'enumerazione può essere convertito nel tipo di enumerazione e rappresenta un valore valido distinto di quel tipo di enumerazione.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.

L'esempio seguente dichiara un tipo di enumerazione denominato Alignment con un tipo sottostante di 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
}

Come illustrato nell'esempio precedente, una dichiarazione di membro di enumerazione può includere un'espressione costante che specifica il valore del membro.As shown by the previous example, an enum member declaration can include a constant expression that specifies the value of the member. Il valore costante per ogni membro di enumerazione deve essere compreso nell'intervallo del tipo sottostante dell'enumerazione.The constant value for each enum member must be in the range of the underlying type of the enum. Quando una dichiarazione di membro di enumerazione non specifica in modo esplicito un valore, il membro viene assegnato il valore zero (se è il primo membro nel tipo di enumerazione) o il valore del membro enum testualmente precedente più uno.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.

I valori di enumerazione possono essere convertiti in valori integrali e viceversa usando i cast di tipo.Enum values can be converted to integral values and vice versa using type casts. Esempio:For example

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

Il valore predefinito di qualsiasi tipo di enumerazione è il valore integrale zero convertito nel tipo di enumerazione.The default value of any enum type is the integral value zero converted to the enum type. Nei casi in cui le variabili vengono automaticamente inizializzate su un valore predefinito, questo è il valore assegnato alle variabili dei tipi enum.In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. Affinché il valore predefinito di un tipo di enumerazione per rendere facilmente disponibile, il valore letterale 0 converte in modo implicito a qualsiasi tipo di enumerazione.In order for the default value of an enum type to be easily available, the literal 0 implicitly converts to any enum type. Di conseguenza, quanto riportato di seguito è consentito.Thus, the following is permitted.

Color c = 0;

DelegatiDelegates

Un tipo delegato rappresenta riferimenti ai metodi con un elenco di parametri e un tipo restituito particolari.A delegate type represents references to methods with a particular parameter list and return type. I delegati consentono di trattare i metodi come entità che è possibile assegnare a variabili e passare come parametri.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. I delegati sono simili al concetto di puntatori a funzione disponibili in altri linguaggi. A differenza dei puntatori a funzione, tuttavia, i delegati sono orientati agli oggetti e indipendenti dai tipi.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.

Nell'esempio seguente viene dichiarato e usato un tipo delegato denominato 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);
    }
}

Un'istanza del tipo delegato Function può fare riferimento a qualsiasi metodo che accetta un argomento double e restituisce un valore double.An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. Il Apply metodo si applica un determinato Function agli elementi di un double[], restituendo un double[] con i risultati.The Apply method applies a given Function to the elements of a double[], returning a double[] with the results. Nel metodo Main, Apply viene usato per applicare a double[] tre funzioni differenti.In the Main method, Apply is used to apply three different functions to a double[].

Un delegato può fare riferimento a un metodo statico, come Square o Math.Sin nell'esempio precedente, o a un metodo di istanza, come m.Multiply nell'esempio precedente.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). Un delegato che fa riferimento a un metodo di istanza fa riferimento anche a un oggetto particolare. Quando il metodo di istanza viene richiamato tramite il delegato, l'oggetto diventa this nella chiamata.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.

I delegati possono essere creati anche mediante funzioni anonime, ovvero "metodi inline" creati in tempo reale.Delegates can also be created using anonymous functions, which are "inline methods" that are created on the fly. Le funzioni anonime possono vedere le variabili locali dei metodi circostanti.Anonymous functions can see the local variables of the surrounding methods. Di conseguenza, il precedente esempio di moltiplicatore può essere scritto più facilmente senza usare un 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);

Una proprietà interessante e utile di un delegato consiste nel fatto che non conosce o non prende in considerazione la classe del metodo a cui fa riferimento. Ciò che conta è che il metodo a cui un delegato fa riferimento abbia gli stessi parametri e restituisca lo stesso tipo del delegato in questione.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.

AttributiAttributes

Tipi, membri e altre entità di un programma C# supportano modificatori che controllano alcuni aspetti del loro comportamento.Types, members, and other entities in a C# program support modifiers that control certain aspects of their behavior. L'accessibilità di un metodo, ad esempio, è controllata con i modificatori public, protected, internal e private.For example, the accessibility of a method is controlled using the public, protected, internal, and private modifiers. Il linguaggio C# generalizza questa funzionalità in modo che i tipi di informazioni dichiarative definiti dall'utente possano essere associati a entità di programma e recuperati in fase di esecuzione.C# generalizes this capability such that user-defined types of declarative information can be attached to program entities and retrieved at run-time. I programmi specificano queste informazioni dichiarative aggiuntive definendo e usando attributi.Programs specify this additional declarative information by defining and using attributes.

Nell'esempio seguente viene dichiarato un attributo HelpAttribute che può essere inserito in entità di programma per fornire collegamenti alla documentazione correlata.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; }
    }
}

Tutte le classi di attributo derivano dal System.Attribute classe forniti da .NET Framework di base.All attribute classes derive from the System.Attribute base class provided by the .NET Framework. Gli attributi possono essere applicati specificandone il nome (con eventuali argomenti) tra parentesi quadre appena prima della dichiarazione associata.Attributes can be applied by giving their name, along with any arguments, inside square brackets just before the associated declaration. Se il nome dell'attributo termina Attribute, tale parte del nome può essere omessa quando si fa riferimento l'attributo.If an attribute's name ends in Attribute, that part of the name can be omitted when the attribute is referenced. L'attributo HelpAttribute, ad esempio, può essere usato come illustrato di seguito.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) {}
}

Questo esempio associa un HelpAttribute per il Widget classe e un'altra HelpAttribute per il Display metodo nella classe.This example attaches a HelpAttribute to the Widget class and another HelpAttribute to the Display method in the class. I costruttori pubblici di una classe di attributo controllano le informazioni che devono essere specificate quando l'attributo è associato a un'entità di programma.The public constructors of an attribute class control the information that must be provided when the attribute is attached to a program entity. È possibile specificare informazioni aggiuntive facendo riferimento a proprietà di lettura/scrittura pubbliche della classe di attributo, ad esempio il riferimento alla proprietà Topic precedente.Additional information can be provided by referencing public read-write properties of the attribute class (such as the reference to the Topic property previously).

L'esempio seguente illustra come le informazioni sugli attributi per un'entità di programma specificato può essere recuperati in fase di esecuzione usando reflection.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"));
    }
}

Se un attributo viene richiesto tramite reflection, il costruttore della classe di attributo viene richiamato con le informazioni specificate nell'origine del programma e viene restituita l'istanza dell'attributo risultante.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 sono state fornite informazioni aggiuntive tramite proprietà, queste vengono impostate sui valori specificati prima che venga restituita l'istanza dell'attributo.If additional information was provided through properties, those properties are set to the given values before the attribute instance is returned.