C# Language
Metody
Szukaj…
Deklaracja metody
Każda metoda ma unikalny podpis składający się z akcesora ( public
, private
, ...), opcjonalnego modyfikatora ( abstract
), nazwy i, w razie potrzeby, parametrów metody. Uwaga: typ zwrotu nie jest częścią podpisu. Prototyp metody wygląda następująco:
AccessModifier OptionalModifier ReturnType MethodName(InputParameters)
{
//Method body
}
AccessModifier
może być public
, protected
, pirvate
lub domyślnie internal
.
OptionalModifier
może być static
abstract
virtual
override
new
lub sealed
.
ReturnType
może być void
dla braku zwrotu lub może być dowolnego typu z podstawowych, jako int
do klas złożonych.
Metoda może mieć niektóre parametry wejściowe lub nie mieć ich wcale. aby ustawić parametry dla metody, należy zadeklarować każdy z nich jak normalne deklaracje zmiennych (jak int a
), a dla więcej niż jednego parametru należy użyć przecinka między nimi (jak int a, int b
).
Parametry mogą mieć wartości domyślne. w tym celu należy ustawić wartość parametru (np. int a = 0
). jeśli parametr ma wartość domyślną, ustawienie wartości wejściowej jest opcjonalne.
Poniższy przykład metody zwraca sumę dwóch liczb całkowitych:
private int Sum(int a, int b)
{
return a + b;
}
Wywołanie metody
Wywołanie metody statycznej:
// Single argument
System.Console.WriteLine("Hello World");
// Multiple arguments
string name = "User";
System.Console.WriteLine("Hello, {0}!", name);
Wywoływanie metody statycznej i przechowywanie jej wartości zwracanej:
string input = System.Console.ReadLine();
Wywołanie metody wystąpienia:
int x = 42;
// The instance method called here is Int32.ToString()
string xAsString = x.ToString();
Wywołanie metody ogólnej
// Assuming a method 'T[] CreateArray<T>(int size)'
DateTime[] dates = CreateArray<DateTime>(8);
Parametry i argumenty
Metoda może zadeklarować dowolną liczbę parametrów (w tym przykładzie i
, s
i o
są parametrami):
static void DoSomething(int i, string s, object o) {
Console.WriteLine(String.Format("i={0}, s={1}, o={2}", i, s, o));
}
Parametry mogą być używane do przekazywania wartości do metody, aby metoda mogła z nimi pracować. Może to być każdy rodzaj pracy, np. Drukowanie wartości, modyfikowanie obiektu, do którego odnosi się parametr lub przechowywanie wartości.
Kiedy wywołujesz metodę, musisz przekazać rzeczywistą wartość dla każdego parametru. W tym momencie wartości, które faktycznie przekazujesz do wywołania metody, nazywane są Argumentami:
DoSomething(x, "hello", new object());
Rodzaje zwrotów
Metoda może zwrócić albo nic ( void
), albo wartość określonego typu:
// 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";
}
Jeśli twoja metoda określa wartość zwracaną, metoda musi zwrócić wartość. Robisz to za pomocą instrukcji return
. Po osiągnięciu instrukcji return
zwraca określoną wartość i kod po tym czasie nie będzie już uruchamiany (wyjątkami są finally
bloki, które nadal będą wykonywane przed powrotem metody).
Jeśli twoja metoda nic nie zwraca ( void
), nadal możesz użyć instrukcji return
bez wartości, jeśli chcesz natychmiast powrócić z metody Pod koniec takiej metody instrukcja return
nie byłaby jednak potrzebna.
Przykłady prawidłowych instrukcji return
:
return;
return 0;
return x * 2;
return Console.ReadLine();
Zgłoszenie wyjątku może zakończyć wykonywanie metody bez zwracania wartości. Istnieją również bloki iteratora, w których wartości zwracane są generowane za pomocą słowa kluczowego fed, ale są to szczególne przypadki, które nie zostaną wyjaśnione w tym momencie.
Parametry domyślne
Możesz użyć parametrów domyślnych, jeśli chcesz zapewnić opcję pominięcia parametrów:
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")
}
Po wywołaniu takiej metody i pominięciu parametru, dla którego podano wartość domyślną, kompilator wstawia tę wartość domyślną.
Należy pamiętać, że parametry z wartościami domyślnymi należy zapisać po parametrach bez wartości domyślnych.
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);
}
OSTRZEŻENIE : Ponieważ działa w ten sposób, w niektórych przypadkach wartości domyślne mogą być problematyczne. Jeśli zmienisz domyślną wartość parametru metody i nie przekompilujesz wszystkich wywołujących tej metody, wywołujący nadal będą używać domyślnej wartości, która była obecna podczas ich kompilacji, co może powodować niespójności.
Przeciążenie metody
Definicja: Gdy wiele metod o tej samej nazwie jest zadeklarowanych z różnymi parametrami, określa się to jako przeciążenie metody. Przeciążenie metody zazwyczaj reprezentuje funkcje, które są identyczne w swoim celu, ale są napisane tak, aby akceptować różne typy danych jako parametry.
Czynniki wpływające
- Liczba argumentów
- Rodzaj argumentów
- Rodzaj zwrotu **
Rozważ metodę o nazwie Area
, która wykona funkcje obliczeniowe, która przyjmie różne argumenty i zwróci wynik.
Przykład
public string Area(int value1)
{
return String.Format("Area of Square is {0}", value1 * value1);
}
Ta metoda przyjmie jeden argument i zwróci ciąg, jeśli wywołamy metodę z liczbą całkowitą (powiedzmy 5
), wynikiem będzie "Area of Square is 25"
.
public double Area(double value1, double value2)
{
return value1 * value2;
}
Podobnie, jeśli przekażemy dwie podwójne wartości do tej metody, wynik będzie iloczynem dwóch wartości i będą typu podwójnego. Można to wykorzystać do mnożenia, a także do znajdowania obszaru prostokątów
public double Area(double value1)
{
return 3.14 * Math.Pow(value1,2);
}
Można tego użyć specjalnie do znalezienia obszaru koła, który przyjmie podwójną wartość ( radius
) i zwróci kolejną podwójną wartość jako swój obszar.
Każda z tych metod może być wywoływana normalnie bez konfliktu - kompilator zbada parametry każdego wywołania metody, aby ustalić, która wersja Area
musi zostać użyta.
string squareArea = Area(2);
double rectangleArea = Area(32.0, 17.5);
double circleArea = Area(5.0); // all of these are valid and will compile.
** Należy pamiętać, że sam typ zwrotu nie może rozróżniać dwóch metod. Na przykład, jeśli mamy dwie definicje dla Obszaru, które mają te same parametry, na przykład:
public string Area(double width, double height) { ... }
public double Area(double width, double height) { ... }
// This will NOT compile.
Jeśli potrzebujemy, aby nasza klasa używała tych samych nazw metod, które zwracają różne wartości, możemy usunąć problemy niejednoznaczności poprzez wdrożenie interfejsu i jawne zdefiniowanie jego użycia.
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) { ... }
Metoda anonimowa
Anonimowe metody zapewniają technikę przekazywania bloku kodu jako parametru delegowanego. Są to metody z ciałem, ale bez nazwy.
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));
}
}
Prawa dostępu
// 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()