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# presenta le sue radici nella famiglia di linguaggi C e sarà immediatamente familiare ai programmatori 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 da ECMA International come *ECMA-334 _ standard e ISO/IEC come lo standard _ *iso/IEC 23270**.C# is standardized by ECMA International as the ECMA-334 _ standard and by ISO/IEC as the _ ISO/IEC 23270 standard. Il compilatore C# di Microsoft per il .NET Framework è un'implementazione conforme di 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# fornisce costrutti di linguaggio per supportare direttamente questi concetti, rendendo C# un linguaggio molto naturale in cui creare e utilizzare 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# facilitano la costruzione di applicazioni solide e durevoli: Garbage Collection _ recupera automaticamente la memoria occupata dagli oggetti inutilizzati; la _gestione delle eccezioni*_ fornisce un approccio strutturato ed estendibile per il rilevamento e il ripristino degli errori. e la struttura di tipo *indipendente dai tipi di linguaggio rende impossibile leggere le variabili non inizializzate, indicizzare le matrici oltre i limiti o per eseguire cast di tipo non verificati.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 e le librerie C# possano evolversi nel tempo in modo compatibile, è stato enfatizzato il controllo delle versioni nella progettazione di c#.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 della progettazione di C# che sono stati influenzati direttamente dalle considerazioni sul controllo delle versioni includono i virtual override modificatori e separati, le regole per la risoluzione dell'overload del metodo e il supporto per le dichiarazioni esplicite dei membri di interfaccia.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.

Nella parte restante di questo capitolo vengono descritte le funzionalità essenziali del linguaggio C#.The rest of this chapter describes the essential features of the C# language. Sebbene i capitoli successivi descrivano le regole e le eccezioni in modo orientato ai dettagli e talvolta matematico, questo capitolo si impegna per la chiarezza e la 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 è fornire al lettore un'introduzione al linguaggio che faciliterà la scrittura dei primi programmi e la lettura dei capitoli successivi.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 , è possibile compilare il programma con il compilatore Microsoft C# utilizzando la 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 produce un assembly eseguibile denominato hello.exe .which produces an executable assembly named hello.exe. L'output prodotto da questa 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 il 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 dalle librerie di classi .NET Framework, che, per impostazione predefinita, fanno riferimento automaticamente al compilatore Microsoft C#.This class is provided by the .NET Framework class libraries, which, by default, are automatically referenced by the Microsoft C# compiler. Si noti che in C# non è presente una libreria di runtime separata.Note that C# itself does not have a separate runtime library. Il .NET Framework è invece la libreria di runtime di C#.Instead, the .NET Framework is the runtime library of C#.

Struttura del programmaProgram structure

I concetti aziendali chiave in 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 di file .exe o .dll , a seconda che ** implementino o meno le librerie* *.Assemblies typically have the file extension .exe or .dll, depending on whether they implement applications or _*libraries**.

L'esempio:The 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 istruzioni *Intermediate Language _ (il) e informazioni sui simboli nel formato _ Metadata *.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 è archiviato nel file test.cs , quando test.cs viene compilato, è acme.dll possibile fare riferimento all'assembly usando l'opzione del compilatore /r :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

Esistono due tipi di tipi in C#: *tipi valore _ e _ tipi di 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).

I tipi di valore di c# sono ulteriormente divisi in tipi semplici _, _tipi enum_, _tipi di struct_ e _tipi nullable_ e i tipi di riferimento di c# sono ulteriormente divisi in _tipi di classe_, _tipi di interfaccia_, tipi di _matrici*_ 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**.

La tabella seguente fornisce una panoramica del sistema di tipi di C#.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 di 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 modulo, 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.

I due tipi a virgola mobile, float e double , vengono rappresentati usando i formati IEEE 754 a precisione singola a 32 bit e a 64 bit.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.

Il tipo di C# bool viene usato per rappresentare valori booleani, ovvero valori che sono 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.

Nella tabella seguente sono riepilogati i tipi numerici di C#.The following table summarizes C#'s numeric types.

CategoriaCategory BITSBits TipoType Intervallo/precisioneRange/Precision
Integrale con segnoSigned integral 88 sbyte -128... 127-128...127
1616 short -32768... 32, 767-32,768...32,767
3232 int -2147483648... 2, 147, 483, 647-2,147,483,648...2,147,483,647
6464 long -9.223.372.036.854.775.808... 9, 223, 372, 036, 854, 775, 807-9,223,372,036,854,775,808...9,223,372,036,854,775,807
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 a 3,4 × 10 ^ 38, precisione a 7 cifre1.5 × 10^−45 to 3.4 × 10^38, 7-digit precision
6464 double 5,0 × 10 ^ − 324 a 1,7 × 10 ^ 308, precisione di 15 cifre5.0 × 10^−324 to 1.7 × 10^308, 15-digit precision
DecimalDecimal 128128 decimal 1,0 × 10 ^ − 28 a 7,9 × 10 ^ 28, 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 categorie di tipi di C# sono definibili dall'utente: tipi di classe, tipi di struct, tipi di interfaccia, tipi enum e tipi 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 membri dati (campi) e 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 di struct è simile a un tipo di classe in quanto rappresenta una struttura con membri dati e 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, gli struct sono tipi valore e non richiedono l'allocazione dell'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 di funzioni pubbliche.An interface type defines a contract as a named set of public function members. Una classe o uno struct che implementa un'interfaccia deve fornire le implementazioni dei membri della 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 uno 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 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.

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

Un tipo enum è 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 enum corrisponde al 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.

Anche i tipi nullable 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 esiste un tipo nullable corrispondente T? , che può avere 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ò ospitare qualsiasi Integer a 32 bit o il valore null .For instance, int? is a type that can hold any 32 bit integer or the value null.

Il sistema di tipi di C# è unificato in modo che un valore di qualsiasi tipo possa 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 valore vengono trattati come oggetti eseguendo le operazioni *Boxing _ e _ *unboxing *.*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 di valore viene convertito nel tipo object , viene allocata un'istanza dell'oggetto, denominata anche "box", per mantenere il valore e il valore viene copiato in tale casella.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. Viceversa, quando object viene eseguito il cast di un riferimento a un tipo valore, viene eseguito un controllo che l'oggetto a cui si fa riferimento è una casella del tipo di valore corretto e, se il controllo ha esito positivo, il valore nella casella viene copiato.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.

Il sistema di tipi unificato di C# indica efficacemente 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 i percorsi 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.

Il tipo di variabileType of Variable Contenuto possibilePossible 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 di quel tipo esattoA null value or a value of that exact type
object Un riferimento null, un riferimento a un oggetto di qualsiasi tipo di 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 tale tipo di interfaccia o un riferimento a un valore boxed di un tipo di valore che implementa tale tipo di 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 tale tipo di matrice o un riferimento a un'istanza di un tipo di 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 del tipo delegatoA null reference or a reference to an instance of that delegate type

EspressioniExpressions

Le espressioni _ sono costruite 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.

Quando un'espressione contiene più operatori, la *precedenza _ degli operatori controlla 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ò essere sottoposta a 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.

Nella tabella seguente sono riepilogati gli operatori di C#, che elencano le categorie di operatori in ordine di precedenza dal più alto al più basso.The following table summarizes C#'s operators, listing the operator categories in order of precedence from highest to lowest. Gli operatori nella stessa categoria hanno la stessa precedenza.Operators in the same category have equal precedence.

CategoriaCategory EspressioneExpression DescrizioneDescription
PrincipalePrimary 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)
UnariaUnary +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
AdditiveAdditive x + y Addizione, concatenazione di stringhe, combinazione di delegatiAddition, string concatenation, delegate combination
x - y Sottrazione, rimozione di delegatiSubtraction, delegate removal
MAIUSCShift 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 Uguale aEqual
x != y Diverso daNot 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 Valuta y solo se x è trueEvaluates y only if x is true
OR condizionaleConditional OR x || y Valuta y solo se x è falseEvaluates y only if x is false
Null-coalescingNull coalescing x ?? y Restituisce y se x è null , in x caso contrarioEvaluates 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 utilizzate come istruzioni includono chiamate al metodo, allocazioni di oggetti utilizzando l' new operatore, assegnazioni utilizzando = e gli operatori di assegnazione composta, operazioni di incremento e decremento utilizzando gli ++ -- operatori e e le 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.

Le istruzioni di iterazione vengono usate 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.

Le checked unchecked istruzioni e vengono utilizzate per controllare il contesto di controllo dell'overflow per le conversioni e le operazioni aritmetiche di tipo integrale.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 alcuni 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``tryistruzioni ethrow and try statements

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

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

checked``uncheckedistruzioni echecked 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 più importanti dei tipi di C#.*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 le istanze create dinamicamente della classe, 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 oggetti e archiviano i riferimenti a tali 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 i membri statici* *.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 viene fornita una panoramica dei tipi di membri che possono essere contenuti in una classe.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 essere quindi usati nel corpo delle dichiarazioni di classe per definire i membri della classe.The type parameters can then 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 dichiarato per accettare parametri di tipo prende il nome di tipo di classe generico.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 forniti, come Pair<int,string> sopra, viene definito 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à indica che una classe contiene in modo implicito tutti i membri della relativa classe di base, ad eccezione dell'istanza e dei costruttori statici e dei 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 associata 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 il 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. L'assegnazione a un readonly campo può essere eseguita 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 *Method _ è un membro che implementa un calcolo o un'azione che può essere eseguita da un oggetto o da 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. _ I metodi di istanza* sono accessibili tramite istanze della classe._ Instance methods* are accessed through instances of the class.

I metodi hanno un elenco (possibilmente vuoto) di *parametri _, che rappresentano valori o riferimenti a variabili passati al metodo, e un tipo _ * restituito * *, che specifica il tipo di valore calcolato e restituito dal 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 di un metodo è void se non restituisce alcun 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. I Write WriteLine metodi e della System.Console classe sono ottimi esempi di utilizzo delle matrici di parametri.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

Il corpo di un 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 che restituisce non- void , return le istruzioni devono 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 è un 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.

Nell'esempio seguente viene illustrato l'utilizzo della 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

Quando una dichiarazione di metodo di istanza include un virtual modificatore, il metodo viene definito un *metodo virtuale _.When an instance method declaration includes a virtual modifier, the method is said to be a *virtual method _. Quando non virtual è presente alcun modificatore, 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 di runtime* dell'istanza per cui viene eseguita la chiamata determina l'implementazione del metodo effettivo 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 tipo _ in fase di compilazione * dell'istanza è il fattore determinante.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 metodo astratto è un metodo virtuale senza implementazione.An abstract method is a virtual method with no implementation. Un metodo astratto viene dichiarato con il abstract modificatore ed è consentito solo in una classe che è anche 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. (Questo è simile a, ma non deve essere confuso con i tipi di albero delle espressioni introdotti nei 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 oggetto Hashtable che contiene i nomi delle variabili (come chiavi delle voci) e 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 metodo è un metodo astratto virtuale, ovvero le classi derivate non astratte devono 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. L' VariableReference implementazione di un oggetto cerca il nome della variabile in Hashtable 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

Il metodo *Overload _ consente a più metodi nella stessa classe di avere lo stesso nome purché dispongano di 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. Questa sezione descrive gli altri tipi di membri di funzione supportati da C#: costruttori, proprietà, indicizzatori, eventi, operatori e distruttori.This section describes the other kinds of function members supported by C#: constructors, properties, indexers, events, operators, and destructors.

Nel codice seguente viene illustrata una classe generica denominata List<T> , che implementa un elenco di oggetti espandibile.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. Un costruttore statico* è un membro che implementa le azioni necessarie per inizializzare una classe quando 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.

È possibile eseguire l'overload di costruttori di istanze.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. Nelle istruzioni seguenti vengono allocate due List<string> istanze di utilizzando ciascuno dei costruttori della 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

*Properties _ sono un'estensione naturale 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. Le proprietà hanno invece _ funzioni di accesso* che specificano le istruzioni da eseguire quando i relativi valori vengono letti o scritti.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 una get funzione di accesso e/o una set funzione di accesso scritta tra i delimitatori { e } anziché terminare 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à con una funzione di get accesso e una set funzione di accesso è una proprietà di lettura/scrittura , una proprietà che ha solo una get funzione di accesso è una proprietà di sola lettura e una proprietà che ha solo una funzione di set accesso è una 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**.

Una get funzione di accesso corrisponde 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 la destinazione di un'assegnazione, quando si fa riferimento a una proprietà in un'espressione, get viene richiamata la funzione di accesso della proprietà 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.

Una set funzione di accesso corrisponde a un metodo con un solo parametro denominato value e nessun tipo restituito.A set accessor corresponds to a method with a single parameter named value and no return type. Quando si fa riferimento a una proprietà come destinazione di un'assegnazione o come operando di ++ o -- , la set funzione di accesso viene richiamata 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. Le proprietà statiche vengono dichiarate con il 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à, ma a differenza di questa il nome del membro è this seguito da un elenco di parametri scritti 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. Ad 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 una 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 presenti handle di evento, 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. L' Changed evento viene generato dal OnChanged metodo virtuale, che verifica prima di tutto se l'evento è null (ovvero non è 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 di confrontando ognuno degli oggetti contenuti usando i relativi 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

Un 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, non possono avere modificatori di accessibilità e non possono essere richiamati in modo esplicito.Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. Il distruttore di un'istanza viene richiamato automaticamente durante Garbage Collection.The destructor for an instance is invoked automatically during garbage collection.

Per la Garbage Collector è consentita una latitudine ampia per decidere quando raccogliere oggetti ed eseguire distruttori.The garbage collector is allowed wide latitude in deciding when to collect objects and run destructors. In particolare, la tempistica delle chiamate del distruttore non è deterministica e i distruttori possono essere eseguiti su 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 non sono realizzabili altre soluzioni.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 creare 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. L'output prodotto dal frammento di codice seguente, ad esempio, dipende dalla presenza di Point una classe o di 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 è 20 perché 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 è 10 perché l'assegnazione di a a b Crea una copia del valore e questa copia non è interessata dall'assegnazione successiva 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

*Array _ è una struttura di dati che contiene un numero di variabili a cui si accede 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, denominate anche elementi della matrice, sono tutti dello stesso tipo e questo tipo è denominato _ 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. Le istanze di matrice effettive vengono create dinamicamente in fase di esecuzione usando l' new operatore.Actual array instances are created dynamically at run-time using the new operator. L' new operazione specifica la lunghezza della nuova istanza della matrice, che viene quindi corretta 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]);
        }
    }
}

Questo esempio crea e opera su un *Array 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, noto anche come _ Rank* del tipo di matrice, è uno più il numero di virgole scritte tra le 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 vengono allocate una matrice unidimensionale, bidimensionale e 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.

L' new operatore consente di specificare i valori iniziali degli elementi della matrice utilizzando 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. Ad 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 i cast di tipo dinamico per ottenere le IControl implementazioni dell'interfaccia e dell'oggetto IDataBound .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 , il cast ha esito positivo.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 classe precedente EditBox , il Paint metodo dell' IControl interfaccia e il metodo dell' Bind IDataBound interfaccia vengono implementati usando public i 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 implementazioni esplicite di membri di interfaccia, usando le quali la classe o lo struct può evitare di creare 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 fornita dalla classe precedente EditBox può essere richiamata solo convertendo prima il EditBox riferimento al IControl tipo di 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 enum denominato Color con tre valori costanti, 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 tipo sottostante del tipo enum.Each enum type has a corresponding integral type called the underlying type of the enum type. Un tipo enum che non dichiara in modo esplicito un tipo sottostante ha 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 di un tipo enum 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 un tipo enum può assumere 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, è possibile eseguire il cast di qualsiasi valore del tipo sottostante di un'enumerazione al tipo enum ed è un valore valido distinto di tale tipo enum.In particular, any value of the underlying type of an enum can be cast to the enum type and is a distinct valid value of that enum type.

Nell'esempio seguente viene dichiarato un tipo enum 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 enum 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 enum 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 un membro enum non specifica in modo esplicito un valore, al membro viene assegnato il valore zero (se è il primo membro del tipo enum) o il valore del membro enum testuale 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 enum 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. Ad 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 enum è il valore integrale zero convertito nel tipo enum.The default value of any enum type is the integral value zero converted to the enum type. Nei casi in cui le variabili vengono inizializzate automaticamente su un valore predefinito, si tratta del 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 enum sia facilmente disponibile, il valore letterale viene 0 convertito in modo implicito in qualsiasi tipo enum.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 applica un oggetto specificato Function agli elementi di un oggetto double[] , restituendo un oggetto 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. Quindi, l'esempio precedente può essere scritto più facilmente senza usare una 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 attributi derivano dalla System.Attribute classe di base fornita dal .NET Framework.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 di un attributo termina in Attribute , tale parte del nome può essere omessa quando si fa riferimento all'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 connette un oggetto HelpAttribute alla Widget classe e un altro HelpAttribute al 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).

Nell'esempio seguente viene illustrato come recuperare le informazioni sugli attributi per un'entità programma specificata in fase di esecuzione tramite 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.