Megosztás a következőn keresztül:


Módszerek (C# programozási útmutató)

A metódus egy utasítássorozatot tartalmazó kódblokk. Egy program a metódus meghívásával és a szükséges metódusargumentumok megadásával hajtja végre az utasításokat. A C#-ban minden végrehajtott utasítás egy metódus kontextusában történik.

A Main metódus minden C#-alkalmazás belépési pontja, amelyet a program indításakor a közös nyelvi futtatókörnyezet (CLR) hív meg. A legfelső szintű utasításokat használó alkalmazásokban a Main metódust a fordító hozza létre, és tartalmazza az összes legfelső szintű utasítást.

Megjegyzés

Ez a cikk az elnevezett metódusokat ismerteti. A névtelen függvényekről további információt a Lambda-kifejezésekben talál.

Metódusaláírások

A metódusok osztályban, szerkezetben vagy felületen deklarálhatók a hozzáférési szint( például public vagy private, választható módosítók, például abstract vagy sealed), a visszatérési érték, a metódus neve és bármely metódusparaméter megadásával. Ezek a részek együttesen a módszer aláírását képezik.

Fontos

A metódus visszatérési típusa nem része a metódus aláírásának a metódus túlterhelése céljából. Ez azonban a metódus szignatúrájának része, amikor meghatározzák a delegált és a metódus közötti kompatibilitást.

A metódusparaméterek zárójelek közé vannak zárva, és vesszővel vannak elválasztva. Az üres zárójelek azt jelzik, hogy a metódus nem igényel paramétereket. Ez az osztály négy metódust tartalmaz:

abstract class Motorcycle
{
    // Anyone can call this.
    public void StartEngine() {/* Method statements here */ }

    // Only derived classes can call this.
    protected void AddGas(int gallons) { /* Method statements here */ }

    // Derived classes can override the base class implementation.
    public virtual int Drive(int miles, int speed) { /* Method statements here */ return 1; }

    // Derived classes must implement this.
    public abstract double GetTopSpeed();
}

Metódushozzáférés

Egy metódus meghívása egy objektumon olyan, mint egy mező elérése. Az objektum neve után adjon hozzá egy pontot, a metódus nevét és zárójeleket. Az argumentumok a zárójelek között vannak felsorolva, és vesszővel vannak elválasztva. Az osztály metódusai ezért az Motorcycle alábbi példához hasonlóan hívhatók meg:

class TestMotorcycle : Motorcycle
{
    public override double GetTopSpeed()
    {
        return 108.4;
    }

    static void Main()
    {
        TestMotorcycle moto = new TestMotorcycle();

        moto.StartEngine();
        moto.AddGas(15);
        moto.Drive(5, 20);
        double speed = moto.GetTopSpeed();
        Console.WriteLine($"My top speed is {speed}");
    }
}

Metódusparaméterek és argumentumok

A metódusdefiníció megadja a szükséges paraméterek nevét és típusait. Amikor a kód meghívja a metódust, konkrét értékeket, úgynevezett argumentumokat biztosít az egyes paraméterekhez. Az argumentumoknak kompatibilisnek kell lenniük a paramétertípussal, de a hívó kódban használt argumentumnévnek (ha van ilyen) nem kell megegyeznie a metódusban definiált paraméterrel. Például:

public void Caller()
{
    int numA = 4;
    // Call with an int variable.
    int productA = Square(numA);

    int numB = 32;
    // Call with another int variable.
    int productB = Square(numB);

    // Call with an integer literal.
    int productC = Square(12);

    // Call with an expression that evaluates to int.
    productC = Square(productA * 3);
}

int Square(int i)
{
    // Store input argument in a local variable.
    int input = i;
    return input * input;
}

Továbbítás hivatkozással és érték szerinti átadással

Alapértelmezés szerint, amikor egy értéktípus egy példányát átadják egy metódusnak, annak a másolata kerül átadásra, nem maga a példány. Ezért az argumentum módosítása nincs hatással az eredeti példányra a hívási metódusban. Ha egy értéktípusú példányt hivatkozás alapján szeretne átadni, használja a(z) ref kulcsszót. További információ: Passing Value-Type Parameters.

Amikor egy hivatkozástípusú objektumot átad egy metódusnak, az objektumra mutató hivatkozást ad át. Ez azt jelenti, hogy a metódus nem magát az objektumot kapja meg, hanem egy argumentumot, amely az objektum helyét jelzi. Ha ezzel a hivatkozással módosítja az objektum egy tagját, a változás a hívási metódus argumentumában is megjelenik, még akkor is, ha az objektumot érték szerint adja át.

A kulcsszó használatával class létrehozhat egy referenciatípust, ahogyan az az alábbi példában is látható:

public class SampleRefType
{
    public int value;
}

Most, ha egy ilyen típuson alapuló objektumot ad át egy metódusnak, az objektumra mutató hivatkozást ad át. Az alábbi példa egy típusobjektumot SampleRefType ad át a metódusnak ModifyObject:

public static void TestRefType()
{
    SampleRefType rt = new SampleRefType();
    rt.value = 44;
    ModifyObject(rt);
    Console.WriteLine(rt.value);
}

static void ModifyObject(SampleRefType obj)
{
    obj.value = 33;
}

A példa lényegében ugyanazt teszi, mint az előző példában, amikor egy argumentumot érték szerint ad át egy metódusnak. Mivel azonban referenciatípust használ, az eredmény más. A paraméter ModifyObjectmezőjében valueobj végrehajtott módosítás az argumentum valuemezőjét is módosítja rt a TestRefType metódusban. A TestRefType metódus kimenetként a 33-at jeleníti meg.

További információ a referenciatípusok hivatkozás és érték szerinti átadásáról: Reference-Type paraméterek és referenciatípusok átadása.

Visszaadott értékek

A metódusok visszaadhatnak egy értéket a hívónak. Ha a visszatérési típus (a metódus neve előtt felsorolt típus) nemvoid, a metódus az utasítással visszaadhatja az returnértéket. A kulcsszóval és a visszatérési típusnak megfelelő értékkel rendelkező return utasítás ezt az értéket adja vissza a metódushívónak.

Az érték visszaadható a hívónak érték vagy hivatkozás alapján. A rendszer hivatkozással adja vissza az értékeket a hívónak, ha a ref metódus-aláírásban a kulcsszó szerepel, és az egyes return kulcsszavakat követi. Az alábbi metódusaírás és visszatérési utasítás például azt jelzi, hogy a metódus egy, a hívóra hivatkozva elnevezett estDistance változót ad vissza.

public ref double GetEstimatedDistance()
{
    return ref estDistance;
}

A return kulcsszó a metódus végrehajtását is leállítja. Ha a visszatérési típus az void, return akkor az érték nélküli utasítás továbbra is hasznos a metódus végrehajtásának leállításához. A return kulcsszó nélkül a metódus leáll, amikor eléri a kódblokk végét. Nem void visszatérési típusú metódusok esetén kötelező használni a return kulcsszót az érték visszaadásához. Ez a két módszer például a return kulcsszót használja egész számok visszaadására:

class SimpleMath
{
    public int AddTwoNumbers(int number1, int number2)
    {
        return number1 + number2;
    }

    public int SquareANumber(int number)
    {
        return number * number;
    }
}

Egy metódusból visszaadott érték használatához a hívó metódus bárhol használhatja magát a metódushívást, ahol egy azonos típusú érték elegendő lenne. A visszatérési értéket egy változóhoz is hozzárendelheti. A következő két példakód például ugyanazt a célt valósítja meg:

int result = obj.AddTwoNumbers(1, 2);
result = obj.SquareANumber(result);
// The result is 9.
Console.WriteLine(result);
result = obj.SquareANumber(obj.AddTwoNumbers(1, 2));
// The result is 9.
Console.WriteLine(result);

Helyi változó, ebben az esetben a result, érték tárolására nem kötelezően használandó. Segíthet a kód olvashatóságában, vagy szükség lehet rá, ha az argumentum eredeti értékét a metódus teljes hatókörében kell tárolnia.

Ha egy metódus alapján visszaadott értéket szeretne használni, deklarálnia kell egy ref helyi változót, ha módosítani szeretné annak értékét. Ha például a Planet.GetEstimatedDistance metódus hivatkozással ad vissza egy Double értéket, a következő kóddal definiálhatja ref helyi változóként:

ref double distance = ref Planet.GetEstimatedDistance();

Ha egy metódus többdimenziós tömböt ad vissza, M, ami módosítja a tömb tartalmát, az nem szükséges, ha a hívó függvény már átadta a tömböt M-be. Előfordulhat, hogy az eredményül kapott tömböt visszaadja M a jó stílus vagy funkcionális értékfolyam érdekében, de ez nem szükséges, mert a C# minden referenciatípust érték szerint ad át, és a tömbhivatkozás értéke a tömbre mutató mutató. A metódusban Ma tömb tartalmának változásait bármely olyan kód megfigyelheti, amely hivatkozik a tömbre, ahogyan az a következő példában látható:

static void Main(string[] args)
{
    int[,] matrix = new int[2, 2];
    FillMatrix(matrix);
    // matrix is now full of -1
}

public static void FillMatrix(int[,] matrix)
{
    for (int i = 0; i < matrix.GetLength(0); i++)
    {
        for (int j = 0; j < matrix.GetLength(1); j++)
        {
            matrix[i, j] = -1;
        }
    }
}

Aszinkron metódusok

Az aszinkron funkcióval explicit visszahívások nélkül hívhat meg aszinkron metódusokat, vagy manuálisan oszthatja fel a kódot több metódusra vagy lambdakifejezésre.

Ha az aszinkron módosítóval jelöl meg egy metódust, használhatja a vár operátort a metódusban. Amikor a vezérlőelem egy várakozási kifejezést ér el az aszinkron metódusban, a vezérlő visszatér a hívóhoz, és a metódus előrehaladása fel van függesztve, amíg a várt feladat be nem fejeződik. Ha a feladat befejeződött, a végrehajtás folytatódhat a metódusban.

Megjegyzés

Az aszinkron metódus akkor tér vissza a hívóhoz, ha vagy az első várt objektummal találkozik, amely még nem fejeződött be, vagy az aszinkron metódus végéhez ér, amelyik előbb következik be.

Az aszinkron metódusok visszatérési Task<TResult>típusa általában az , TaskIAsyncEnumerable<T>vagy void. A void visszatérési típus elsősorban eseménykezelők definiálására szolgál, ahol void visszatérési típusra van szükség. Az void-t visszaadó aszinkron metódus nem várható meg, és a void típusú értékkel visszatérő metódus hívója nem tudja elkapni a metódus által kiváltott kivételeket. Az aszinkron metódusok bármilyen feladathoz hasonló visszatérési típussal rendelkezhetnek.

Az alábbi példában egy aszinkron metódus látható, DelayAsync amelynek visszatérési típusa a következő Task<TResult>. DelayAsync return egy egész számot visszaadó utasítással rendelkezik. Ezért a metódus deklarációjának DelayAsync visszatérési típusával kell rendelkeznie Task<int>. Mivel a visszatérési típus az Task<int>, a await kifejezés DoSomethingAsync kiértékelése egész számokat eredményez, ahogyan az alábbi állítás is mutatja: int result = await delayTask.

A Main metódus egy példa egy aszinkron metódusra, amelynek visszatérési Tasktípusa. A DoSomethingAsync metódusba kerül, és mivel egyetlen sorban van kifejezve, kihagyhatja a async és await kulcsszavakat. Mivel DoSomethingAsync aszinkron metódusról van szó, a hívás DoSomethingAsync feladatát meg kell várni, ahogy az alábbi utasítás is mutatja: await DoSomethingAsync();.

class Program
{
    static Task Main() => DoSomethingAsync();

    static async Task DoSomethingAsync()
    {
        Task<int> delayTask = DelayAsync();
        int result = await delayTask;

        // The previous two statements may be combined into
        // the following statement.
        //int result = await DelayAsync();

        Console.WriteLine($"Result: {result}");
    }

    static async Task<int> DelayAsync()
    {
        await Task.Delay(100);
        return 5;
    }
}
// Example output:
//   Result: 5

Az aszinkron metódusok nem deklarálhatnak ref vagy out paramétereket, de meghívhatnak ilyen paraméterekkel rendelkező metódusokat.

Az aszinkron metódusokkal kapcsolatos további információkért lásd az Aszinkron programozás async és await használatával és a Aszinkron visszatérési típusok című részeket.

Kifejezéstörzs-definíciók

Gyakran előfordul, hogy olyan metódusdefiníciók vannak, amelyek egy kifejezés eredményével azonnal visszatérnek, vagy egyetlen utasítással rendelkeznek a metódus törzseként. Az ilyen metódusok meghatározásához szintaktikai rövidítést használhatunk a =>:

public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public void Print() => Console.WriteLine(First + " " + Last);
// Works with operators, properties, and indexers too.
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);

Ha a metódus visszaadja void vagy aszinkron metódus, akkor a metódus törzsének egy utasításkifejezésnek kell lennie (ugyanaz, mint a lambdas esetében). A tulajdonságok és indexelők esetében csak olvashatóknak kell lenniük, és nem használja a kiegészítő kulcsszót get .

Iterátorok

Az iterátor egyéni iterációt hajt végre egy gyűjteményen, például egy listán vagy tömbön. Az iterátor a hozamvisszautasítással egyenként adja vissza az egyes elemeket. yield return utasítás elérésekor megjegyzik a kód aktuális helyét. A végrehajtás akkor indul újra erről a helyről, amikor az iterátort a következő alkalommal hívják meg.

Egy foreach utasítással meghívhat egy iterátort az ügyfélkódból.

Az iterátor visszatérési típusa lehet IEnumerable, IEnumerable<T>, IAsyncEnumerable<T>, IEnumeratorvagy IEnumerator<T>.

További információ: Iterators.

C# nyelvspecifikáció

További információ: C# nyelvi specifikáció. A nyelvi specifikáció a C#-szintaxis és -használat végleges forrása.

Lásd még