C# Language
metodi
Ricerca…
Dichiarazione di un metodo
Ogni metodo ha una firma univoca che consiste in un accessorio ( public
, private
, ...), un modificatore opzionale ( abstract
), un nome e, se necessario, i parametri del metodo. Nota che il tipo di reso non fa parte della firma. Un prototipo di metodo ha il seguente aspetto:
AccessModifier OptionalModifier ReturnType MethodName(InputParameters)
{
//Method body
}
AccessModifier
può essere public
, protected
, pirvate
o di default internal
.
OptionalModifier
può essere override
virtual
abstract
static
new
o sealed
.
ReturnType
può essere void
per nessun ritorno o può essere di qualsiasi tipo da quelli di base, come int
a classi complesse.
un metodo può avere alcuni o nessun parametro di input. per impostare i parametri per un metodo, devi dichiarare ognuno come le normali dichiarazioni delle variabili (come int a
), e per più di un parametro devi usare una virgola tra loro (come int a, int b
).
I parametri possono avere valori predefiniti. per questo dovresti impostare un valore per il parametro (come int a = 0
). se un parametro ha un valore predefinito, l'impostazione del valore di input è facoltativa.
Il seguente esempio di metodo restituisce la somma di due numeri interi:
private int Sum(int a, int b)
{
return a + b;
}
Chiamare un metodo
Chiamando un metodo statico:
// Single argument
System.Console.WriteLine("Hello World");
// Multiple arguments
string name = "User";
System.Console.WriteLine("Hello, {0}!", name);
Chiamando un metodo statico e memorizzando il suo valore di ritorno:
string input = System.Console.ReadLine();
Chiamando un metodo di istanza:
int x = 42;
// The instance method called here is Int32.ToString()
string xAsString = x.ToString();
Chiamando un metodo generico
// Assuming a method 'T[] CreateArray<T>(int size)'
DateTime[] dates = CreateArray<DateTime>(8);
Parametri e argomenti
Un metodo può dichiarare un numero qualsiasi di parametri (in questo esempio, i
, s
e o
sono i parametri):
static void DoSomething(int i, string s, object o) {
Console.WriteLine(String.Format("i={0}, s={1}, o={2}", i, s, o));
}
I parametri possono essere utilizzati per passare valori in un metodo, in modo che il metodo possa funzionare con essi. Questo può essere ogni tipo di lavoro come la stampa dei valori o l'esecuzione di modifiche all'oggetto a cui fa riferimento un parametro o la memorizzazione dei valori.
Quando chiami il metodo, devi passare un valore reale per ogni parametro. A questo punto, i valori che effettivamente passano alla chiamata al metodo sono chiamati Arguments:
DoSomething(x, "hello", new object());
Tipi di reso
Un metodo non può restituire nulla ( void
) o un valore di un tipo specificato:
// If you don't want to return a value, use void as return type.
static void ReturnsNothing() {
Console.WriteLine("Returns nothing");
}
// If you want to return a value, you need to specify its type.
static string ReturnsHelloWorld() {
return "Hello World";
}
Se il metodo specifica un valore di ritorno, il metodo deve restituire un valore. A tale scopo, con il return
dichiarazione. Una volta che è stata raggiunta un'istruzione return
, restituisce il valore specificato e qualsiasi codice dopo che non sarà più eseguito (le eccezioni sono finally
blocchi, che saranno comunque eseguiti prima che il metodo ritorni).
Se il tuo metodo non restituisce nulla ( void
), puoi comunque utilizzare l'istruzione return
senza un valore se vuoi tornare immediatamente dal metodo. Alla fine di tale metodo, tuttavia, una dichiarazione di return
non sarebbe necessaria.
Esempi di validi return
dichiarazioni:
return;
return 0;
return x * 2;
return Console.ReadLine();
Lanciare un'eccezione può terminare l'esecuzione del metodo senza restituire un valore. Inoltre, ci sono blocchi iteratori, in cui i valori di ritorno sono generati usando la parola chiave yield, ma quelli sono casi speciali che non verranno spiegati a questo punto.
Parametri predefiniti
È possibile utilizzare i parametri predefiniti se si desidera fornire l'opzione per omettere i parametri:
static void SaySomething(string what = "ehh") {
Console.WriteLine(what);
}
static void Main() {
// prints "hello"
SaySomething("hello");
// prints "ehh"
SaySomething(); // The compiler compiles this as if we had typed SaySomething("ehh")
}
Quando si chiama un tale metodo e si omette un parametro per il quale viene fornito un valore predefinito, il compilatore inserisce automaticamente il valore predefinito.
Tenere presente che i parametri con i valori predefiniti devono essere scritti dopo i parametri senza valori predefiniti.
static void SaySomething(string say, string what = "ehh") {
//Correct
Console.WriteLine(say + what);
}
static void SaySomethingElse(string what = "ehh", string say) {
//Incorrect
Console.WriteLine(say + what);
}
ATTENZIONE : poiché funziona in questo modo, i valori predefiniti possono essere problematici in alcuni casi. Se si modifica il valore predefinito di un parametro del metodo e non si ricompilano tutti i chiamanti di quel metodo, tali chiamanti continueranno a utilizzare il valore predefinito che era presente al momento della compilazione, probabilmente causando incoerenze.
Sovraccarico di metodi
Definizione: quando più metodi con lo stesso nome vengono dichiarati con parametri diversi, viene indicato come overload del metodo. L'overloading del metodo in genere rappresenta funzioni identiche nel loro scopo ma vengono scritte per accettare tipi di dati diversi come parametri.
Fattori che influenzano
- Numero di argomenti
- Tipo di argomenti
- Tipo di reso **
Considera un metodo denominato Area
che eseguirà funzioni di calcolo, che accetta vari argomenti e restituisce il risultato.
Esempio
public string Area(int value1)
{
return String.Format("Area of Square is {0}", value1 * value1);
}
Questo metodo accetta un argomento e restituisce una stringa, se chiamiamo il metodo con un numero intero (diciamo 5
) l'output sarà "Area of Square is 25"
.
public double Area(double value1, double value2)
{
return value1 * value2;
}
Allo stesso modo, se passiamo due valori doppi a questo metodo, l'output sarà il prodotto dei due valori e sarà di tipo double. Questo può essere usato per la moltiplicazione e per trovare l'Area dei rettangoli
public double Area(double value1)
{
return 3.14 * Math.Pow(value1,2);
}
Questo può essere usato specialmente per trovare l'area del cerchio, che accetta un doppio valore ( radius
) e restituisce un altro doppio valore come area.
Ognuno di questi metodi può essere chiamato normalmente senza conflitto - il compilatore esaminerà i parametri di ciascuna chiamata di metodo per determinare quale versione di Area
deve essere utilizzata.
string squareArea = Area(2);
double rectangleArea = Area(32.0, 17.5);
double circleArea = Area(5.0); // all of these are valid and will compile.
** Nota che il tipo di ritorno da solo non può distinguere tra due metodi. Ad esempio, se avessimo due definizioni per Area con gli stessi parametri, ad esempio:
public string Area(double width, double height) { ... }
public double Area(double width, double height) { ... }
// This will NOT compile.
Se è necessario che la classe utilizzi gli stessi nomi di metodo che restituiscono valori diversi, è possibile rimuovere i problemi di ambiguità implementando un'interfaccia e definendone esplicitamente l'utilizzo.
public interface IAreaCalculatorString {
public string Area(double width, double height);
}
public class AreaCalculator : IAreaCalculatorString {
public string IAreaCalculatorString.Area(double width, double height) { ... }
// Note that the method call now explicitly says it will be used when called through
// the IAreaCalculatorString interface, allowing us to resolve the ambiguity.
public double Area(double width, double height) { ... }
Metodo anonimo
I metodi anonimi forniscono una tecnica per passare un blocco di codice come parametro delegato. Sono metodi con un corpo, ma nessun nome.
delegate int IntOp(int lhs, int rhs);
class Program
{
static void Main(string[] args)
{
// C# 2.0 definition
IntOp add = delegate(int lhs, int rhs)
{
return lhs + rhs;
};
// C# 3.0 definition
IntOp mul = (lhs, rhs) =>
{
return lhs * rhs;
};
// C# 3.0 definition - shorthand
IntOp sub = (lhs, rhs) => lhs - rhs;
// Calling each method
Console.WriteLine("2 + 3 = " + add(2, 3));
Console.WriteLine("2 * 3 = " + mul(2, 3));
Console.WriteLine("2 - 3 = " + sub(2, 3));
}
}
Diritti di accesso
// static: is callable on a class even when no instance of the class has been created
public static void MyMethod()
// virtual: can be called or overridden in an inherited class
public virtual void MyMethod()
// internal: access is limited within the current assembly
internal void MyMethod()
//private: access is limited only within the same class
private void MyMethod()
//public: access right from every class / assembly
public void MyMethod()
//protected: access is limited to the containing class or types derived from it
protected void MyMethod()
//protected internal: access is limited to the current assembly or types derived from the containing class.
protected internal void MyMethod()