Sdílet prostřednictvím


Parametry a modifikátory metody

Ve výchozím nastavení se argumenty v jazyce C# předávají funkcím podle hodnoty. To znamená, že se metodě předá kopie proměnné. Pro typy hodnot (struct) se do metody předá kopie hodnoty . U typů odkazu (class) se metodě předá kopie odkazu . Modifikátory parametrů umožňují předávat argumenty odkazem.

Vzhledem k tomu, že struktura je typ hodnoty , metoda přijímá a pracuje s kopií argumentu při předání struktury podle hodnoty metodě. Metoda nemá přístup k původní struktuře ve volající metodě, a proto ji nemůže žádným způsobem změnit. Metoda může změnit pouze kopii.

Instance třídy je odkazový typ , nikoli typ hodnoty. Pokud je typ odkazu předán hodnotou metodě, metoda obdrží kopii odkazu na instanci. Obě proměnné odkazují na stejný objekt. Parametr je kopie odkazu. Volaná metoda nemůže změnit přiřazení instance ve volající metodě. Volaná metoda však může použít kopii odkazu pro přístup k členům instance. Pokud volána metoda změní člen instance, volající metoda také uvidí tyto změny, protože odkazuje na stejnou instanci.

Předání podle hodnoty a předání referencí

Všechny příklady v této části používají následující dva typy record k ilustraci rozdílů mezi typy class a typy struct:

public record struct Point(int X, int Y);
// This doesn't use a primary constructor because the properties implemented for `record` types are 
// readonly in record class types. That would prevent the mutations necessary for this example.
public record class Point3D
{
    public int X { get; set; }
    public int Y { get; set; }
    public int Z { get; set; }
}

Výstup následujícího příkladu znázorňuje rozdíl mezi předáním typu struktury podle hodnoty a předáním typu třídy podle hodnoty. Obě metody Mutate mění hodnoty vlastností argumentu. Pokud je parametr struct typem, tyto změny se provádějí v kopii dat argumentu. Pokud je parametr typu class, tyto změny se provádějí v instanci odkazované argumentem:

public class PassTypesByValue
{
    public static void Mutate(Point pt)
    {
        Console.WriteLine($"\tEnter {nameof(Mutate)}:\t\t{pt}");
        pt.X = 19;
        pt.Y = 23;

        Console.WriteLine($"\tExit {nameof(Mutate)}:\t\t{pt}");
    }
    public static void Mutate(Point3D pt)
    {
        Console.WriteLine($"\tEnter {nameof(Mutate)}:\t\t{pt}");
        pt.X = 19;
        pt.Y = 23;
        pt.Z = 42;

        Console.WriteLine($"\tExit {nameof(Mutate)}:\t\t{pt}");
    }

    public static void TestPassTypesByValue()
    {
        Console.WriteLine("===== Value Types =====");

        var ptStruct = new Point { X = 1, Y = 2 };
        Console.WriteLine($"After initialization:\t\t{ptStruct}");

        Mutate(ptStruct);

        Console.WriteLine($"After called {nameof(Mutate)}:\t\t{ptStruct}");

        Console.WriteLine("===== Reference Types =====");

        var ptClass = new Point3D { X = 1, Y = 2, Z = 3 };

        Console.WriteLine($"After initialization:\t\t{ptClass}");

        Mutate(ptClass);
        Console.WriteLine($"After called {nameof(Mutate)}:\t\t{ptClass}");

        // Output:
        // ===== Value Types =====
        // After initialization:           Point { X = 1, Y = 2 }
        //         Enter Mutate:           Point { X = 1, Y = 2 }
        //         Exit Mutate:            Point { X = 19, Y = 23 }
        // After called Mutate:            Point { X = 1, Y = 2 }
        // ===== Reference Types =====
        // After initialization:           Point3D { X = 1, Y = 2, Z = 3 }
        //         Enter Mutate:           Point3D { X = 1, Y = 2, Z = 3 }
        //         Exit Mutate:            Point3D { X = 19, Y = 23, Z = 42 }
        // After called Mutate:            Point3D { X = 19, Y = 23, Z = 42 }
    }
}

Modifikátor ref je jedním ze způsobů, jak předat argumenty odkazem metodám. Následující kód se řídí předchozím příkladem, ale předává parametry odkazem. Změny typu struct jsou viditelné v metodě volající, když je struktura předána odkazem. Když je typ odkazu předán odkazem, nedochází k žádné sémantické změně.

public class PassTypesByReference
{
    public static void Mutate(ref Point pt)
    {
        Console.WriteLine($"\tEnter {nameof(Mutate)}:\t\t{pt}");
        pt.X = 19;
        pt.Y = 23;

        Console.WriteLine($"\tExit {nameof(Mutate)}:\t\t{pt}");
    }
    public static void Mutate(ref Point3D pt)
    {
        Console.WriteLine($"\tEnter {nameof(Mutate)}:\t\t{pt}");
        pt.X = 19;
        pt.Y = 23;
        pt.Z = 42;

        Console.WriteLine($"\tExit {nameof(Mutate)}:\t\t{pt}");
    }

    public static void TestPassTypesByReference()
    {
        Console.WriteLine("===== Value Types =====");

        var pStruct = new Point { X = 1, Y = 2 };
        Console.WriteLine($"After initialization:\t\t{pStruct}");

        Mutate(ref pStruct);

        Console.WriteLine($"After called {nameof(Mutate)}:\t\t{pStruct}");

        Console.WriteLine("===== Reference Types =====");

        var pClass = new Point3D { X = 1, Y = 2, Z = 3 };

        Console.WriteLine($"After initialization:\t\t{pClass}");

        Mutate(ref pClass);
        Console.WriteLine($"After called {nameof(Mutate)}:\t\t{pClass}");

        // Output:
        // ===== Value Types =====
        // After initialization:           Point { X = 1, Y = 2 }
        //         Enter Mutate:           Point { X = 1, Y = 2 }
        //         Exit Mutate:            Point { X = 19, Y = 23 }
        // After called Mutate:            Point { X = 19, Y = 23 }
        // ===== Reference Types =====
        // After initialization:           Point3D { X = 1, Y = 2, Z = 3 }
        //         Enter Mutate:           Point3D { X = 1, Y = 2, Z = 3 }
        //         Exit Mutate:            Point3D { X = 19, Y = 23, Z = 42 }
        // After called Mutate:            Point3D { X = 19, Y = 23, Z = 42 }
    }
}

Předchozí příklady upravily vlastnosti parametru. Metoda může také změnit přiřazení parametru k nové hodnotě. Přiřazení se chová odlišně pro typy struktur a typy tříd při předávání podle hodnoty nebo podle odkazu. Následující příklad ukazuje, jak se typy struktur a typy tříd chovají při opětovném přiřazení parametrů předaných hodnotou:

public class PassByValueReassignment
{
    public static void Reassign(Point pt)
    {
        Console.WriteLine($"\tEnter {nameof(Reassign)}:\t\t{pt}");
        pt = new Point { X = 13, Y = 29 };

        Console.WriteLine($"\tExit {nameof(Reassign)}:\t\t{pt}");
    }

    public static void Reassign(Point3D pt)
    {
        Console.WriteLine($"\tEnter {nameof(Reassign)}:\t\t{pt}");
        pt = new Point3D { X = 13, Y = 29, Z = -42 };

        Console.WriteLine($"\tExit {nameof(Reassign)}:\t\t{pt}");
    }

    public static void TestPassByValueReassignment()
    {
        Console.WriteLine("===== Value Types =====");

        var ptStruct = new Point { X = 1, Y = 2 };
        Console.WriteLine($"After initialization:\t\t{ptStruct}");

        Reassign(ptStruct);

        Console.WriteLine($"After called {nameof(Reassign)}:\t\t{ptStruct}");

        Console.WriteLine("===== Reference Types =====");

        var ptClass = new Point3D { X = 1, Y = 2, Z = 3 };

        Console.WriteLine($"After initialization:\t\t{ptClass}");

        Reassign(ptClass);
        Console.WriteLine($"After called {nameof(Reassign)}:\t\t{ptClass}");

        // Output:
        // ===== Value Types =====
        // After initialization:           Point { X = 1, Y = 2 }
        //         Enter Reassign:         Point { X = 1, Y = 2 }
        //         Exit Reassign:          Point { X = 13, Y = 29 }
        // After called Reassign:          Point { X = 1, Y = 2 }
        // ===== Reference Types =====
        // After initialization:           Point3D { X = 1, Y = 2, Z = 3 }
        //         Enter Reassign:         Point3D { X = 1, Y = 2, Z = 3 }
        //         Exit Reassign:          Point3D { X = 13, Y = 29, Z = -42 }
        // After called Reassign:          Point3D { X = 1, Y = 2, Z = 3 }
    }
}

Předchozí ukázka ukazuje, že když přiřadíte parametru novou hodnotu, tato změna není viditelná z volající metody, bez ohledu na to, zda je typ hodnotový nebo odkazový. Následující příklad ukazuje chování při opětovném přiřazení parametru, který byl předán odkazem:

public class PassByReferenceReassignment
{
    public static void Reassign(ref Point pt)
    {
        Console.WriteLine($"\tEnter {nameof(Reassign)}:\t\t{pt}");
        pt = new Point { X = 13, Y = 29 };

        Console.WriteLine($"\tExit {nameof(Reassign)}:\t\t{pt}");
    }

    public static void Reassign(ref Point3D pt)
    {
        Console.WriteLine($"\tEnter {nameof(Reassign)}:\t\t{pt}");
        pt = new Point3D { X = 13, Y = 29, Z = -42 };

        Console.WriteLine($"\tExit {nameof(Reassign)}:\t\t{pt}");
    }

    public static void TestPassByReferenceReassignment()
    {
        Console.WriteLine("===== Value Types =====");

        var ptStruct = new Point { X = 1, Y = 2 };
        Console.WriteLine($"After initialization:\t\t{ptStruct}");

        Reassign(ref ptStruct);

        Console.WriteLine($"After called {nameof(Reassign)}:\t\t{ptStruct}");

        Console.WriteLine("===== Reference Types =====");

        var ptClass = new Point3D { X = 1, Y = 2, Z = 3 };

        Console.WriteLine($"After initialization:\t\t{ptClass}");

        Reassign(ref ptClass);
        Console.WriteLine($"After called {nameof(Reassign)}:\t\t{ptClass}");

        // Output:
        // ===== Value Types =====
        // After initialization:           Point { X = 1, Y = 2 }
        //         Enter Reassign:         Point { X = 1, Y = 2 }
        //         Exit Reassign:          Point { X = 13, Y = 29 }
        // After called Reassign:          Point { X = 13, Y = 29 }
        // ===== Reference Types =====
        // After initialization:           Point3D { X = 1, Y = 2, Z = 3 }
        //         Enter Reassign:         Point3D { X = 1, Y = 2, Z = 3 }
        //         Exit Reassign:          Point3D { X = 13, Y = 29, Z = -42 }
        // After called Reassign:          Point3D { X = 13, Y = 29, Z = -42 }
    }
}

Předchozí příklad ukazuje, jak se v kontextu volání zobrazí změna přiřazení hodnoty parametru předaného odkazem.

Bezpečný kontext odkazů a hodnot

Metody mohou ukládat hodnoty parametrů v polích. Když jsou parametry předány podle hodnoty, to je obvykle bezpečné. Hodnoty se zkopírují a při uložení do pole jsou dostupné odkazové typy. Předání parametrů odkazem vyžaduje, aby kompilátor definoval, kdy je bezpečné přiřadit odkaz na novou proměnnou. Pro každý výraz kompilátor definuje bezpečný kontext , který ohraničuje přístup k výrazu nebo proměnné. Kompilátor používá dva obory: bezpečný kontext a kontext ref-safe.

  • Bezpečný kontext definuje obor, kde se dá bezpečně přistupovat k libovolnému výrazu.
  • Kontext ref-safe definuje obor, kde lze bezpečně přistupovat k libovolnému výrazu nebo ho upravit.

Neformálně si tyto obory můžete představit jako mechanismus, který zajistí, že váš kód nikdy nebude přistupovat k odkazu nebo ho nebude modifikovat. Odkaz je platný, pokud odkazuje na platný objekt nebo strukturu. Bezpečný kontext definuje, kdy lze proměnnou přiřadit nebo znovu přiřadit. Kontext ref-safe definuje, kdy lze proměnnou přiřadit odkaz nebo znovu přiřadit odkaz. Přiřazení přiřadí proměnnou nové hodnotě; Přiřazení odkazu přiřadí proměnnou, která odkazuje na jiné umístění úložiště.

Parametry odkazu

Pro deklaraci parametru použijete jeden z následujících modifikátorů, který předá argumenty odkazem místo hodnoty:

  • ref: Argument musí být inicializován před voláním metody. Metoda může parametru přiřadit novou hodnotu, ale není k tomu nutná.
  • out: Volající metoda není nutná k inicializaci argumentu před voláním metody. Metoda musí přiřadit hodnotu parametru.
  • ref readonly: Argument musí být inicializován před voláním metody. Metoda nemůže k parametru přiřadit novou hodnotu.
  • in: Argument musí být inicializován před voláním metody. Metoda nemůže k parametru přiřadit novou hodnotu. Kompilátor může vytvořit dočasnou proměnnou pro uložení kopie argumentu na in parametry.

Parametr předaný odkazem je referenční proměnná. Nemá vlastní hodnotu. Místo toho odkazuje na jinou proměnnou, která se nazývá její referenční. Referenční proměnné mohou být ref přiřazeny, což změní jejich předmět.

Členové třídy nemohou mít podpisy, které se liší pouze pomocí ref, ref readonly, innebo out. K chybě kompilátoru dochází v případě, že jediný rozdíl mezi dvěma členy typu je, že jeden z nich má ref parametr a druhý má outparametr , ref readonlynebo in parametr. Metody však mohou být přetíženy, pokud jedna metoda má ref, ref readonly, in, nebo out parametr a druhý má parametr, který je předán hodnotou, jak je znázorněno v následujícím příkladu. V jiných situacích, které vyžadují porovnávání podpisů, jako je skrytí nebo přepsání, inref, ref readonlya out jsou součástí podpisu a vzájemně se neshodují.

Pokud má parametr jeden z předchozích modifikátorů, může mít odpovídající argument kompatibilní modifikátor:

  • Argument parametru refref musí obsahovat modifikátor.
  • Argument parametru outout musí obsahovat modifikátor.
  • Argument parametru in může volitelně obsahovat in modifikátor. ref Pokud je modifikátor použit v argumentu místo toho, kompilátor vydá upozornění.
  • Argument parametru ref readonly by měl obsahovat buď inref modifikátory, ale ne obojí. Pokud není zahrnut ani jeden modifikátor, kompilátor vydá upozornění.

Když použijete tyto modifikátory, popisují způsob použití argumentu:

  • ref znamená, že metoda může číst nebo zapisovat hodnotu argumentu.
  • out znamená, že metoda nastaví hodnotu argumentu.
  • ref readonly znamená, že metoda čte, ale nemůže zapsat hodnotu argumentu. Argument by měl být předán odkazem.
  • in znamená, že metoda čte, ale nemůže zapsat hodnotu argumentu. Argument bude předán odkazem nebo dočasnou proměnnou.

V následujících typech metod nemůžete použít předchozí modifikátory parametrů:

Metody rozšíření mají také omezení použití těchto klíčových slov argumentu:

  • Klíčové out slovo nelze použít u prvního argumentu metody rozšíření.
  • Klíčové ref slovo nelze použít u prvního argumentu metody rozšíření, pokud argument není struct, nebo obecný typ není omezen na strukturu.
  • Klíčová ref readonly slova a in klíčová slova nelze použít, pokud není prvním argumentem struct.
  • Klíčová ref readonly slova a in klíčová slova nelze použít u žádného obecného typu, i když je omezena na strukturu.

Vlastnosti nejsou proměnné. Jsou to metody. Vlastnosti nemohou být argumenty parametrů ref .

ref modifikátor parametrů

Pokud chcete použít ref parametr, musí definice metody i volající metoda explicitně použít ref klíčové slovo, jak je znázorněno v následujícím příkladu. (Kromě toho, že volající metoda může vynechat ref při volání COM.)

void Method(ref int refArgument)
{
    refArgument = refArgument + 44;
}

int number = 1;
Method(ref number);
Console.WriteLine(number);
// Output: 45

Před předáním argumentu parametru ref musí být inicializován.

out modifikátor parametrů

Pokud chcete použít out parametr, musí definice metody i volající metoda explicitně použít out klíčové slovo. Příklad:

int initializeInMethod;
OutArgExample(out initializeInMethod);
Console.WriteLine(initializeInMethod);     // value is now 44

void OutArgExample(out int number)
{
    number = 44;
}

Proměnné předané jako out argumenty nemusí být inicializovány před předáním volání metody. Volaná metoda je však nutná k přiřazení hodnoty před vrácením metody.

Dekonstrukční metody deklarují své parametry pomocí modifikátoru out pro vrácení více hodnot. Jiné metody mohou vrátit řazené kolekce členů hodnot pro více vrácených hodnot.

Před předáním proměnné jako argumentu můžete deklarovat proměnnou v samostatném out příkazu. Můžete také deklarovat out proměnnou v seznamu argumentů volání metody, nikoli v samostatné deklaraci proměnné. out Deklarace proměnných vytvářejí kompaktnější, čitelný kód a také vám brání neúmyslně přiřazovat hodnotu proměnné před voláním metody. Následující příklad definuje proměnnou number ve volání Int32.TryParse metoda.

string numberAsString = "1640";

if (Int32.TryParse(numberAsString, out int number))
    Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
    Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
//       Converted '1640' to 1640

Můžete také deklarovat implicitně zatypovanou místní proměnnou.

ref readonly modifikátor

ref readonly Modifikátor musí být obsažen v deklaraci metody. Modifikátor v lokalitě volání je volitelný. in Lze použít buď modifikátor, nebo ref modifikátor. ref readonly Modifikátor není platný na webu volání. Který modifikátor, který použijete na webu volání, může pomoct popsat charakteristiky argumentu. Můžete použít ref pouze v případě, že je argument proměnnou a je zapisovatelný. Argument lze použít in pouze v případech, kdy je argument proměnnou. Může být zapisovatelný nebo jen pro čtení. Pokud argument není proměnnou, nemůžete přidat ani modifikátor, ale jedná se o výraz. Následující příklady ukazují tyto podmínky. Následující metoda používá ref readonly modifikátor k označení, že velká struktura by měla být předána odkazem z důvodů výkonu:

public static void ForceByRef(ref readonly OptionStruct thing)
{
    // elided
}

Metodu můžete volat pomocí nebo ref modifikátoruin. Pokud modifikátor vynecháte, kompilátor vydá upozornění. Pokud je argument výrazem, nikoli proměnnou, nemůžete přidat in ani ref modifikátory, takže byste měli potlačit upozornění:

ForceByRef(in options);
ForceByRef(ref options);
ForceByRef(options); // Warning! variable should be passed with `ref` or `in`
ForceByRef(new OptionStruct()); // Warning, but an expression, so no variable to reference

Pokud je proměnná proměnná proměnná readonly , musíte použít in modifikátor. Kompilátor vydá chybu, pokud místo toho použijete ref modifikátor.

ref readonly Modifikátor označuje, že metoda očekává, že argument bude proměnnou, nikoli výraz, který není proměnnou. Příklady výrazů, které nejsou proměnnými, jsou konstanty, návratové hodnoty metody a vlastnosti. Pokud argument není proměnná, kompilátor vydá upozornění.

in modifikátor parametrů

in Modifikátor je vyžadován v deklaraci metody, ale nepotřebné v lokalitě volání.

int readonlyArgument = 44;
InArgExample(readonlyArgument);
Console.WriteLine(readonlyArgument);     // value is still 44

void InArgExample(in int number)
{
    // Uncomment the following line to see error CS8331
    //number = 19;
}

in Modifikátor umožňuje kompilátoru vytvořit dočasnou proměnnou argumentu a předat do argumentu jen pro čtení odkaz. Kompilátor vždy vytvoří dočasnou proměnnou, pokud je nutné argument převést, pokud existuje implicitní převod z typu argumentu nebo pokud je argument hodnotou, která není proměnnou. Například pokud je argument literálovou hodnotou nebo hodnota vrácená z přístupového objektu vlastnosti. Pokud vaše rozhraní API vyžaduje předání argumentu odkazem, zvolte ref readonly místo modifikátoru in modifikátor.

Metody definované pomocí in parametrů potenciálně získávají optimalizaci výkonu. Některé struct argumenty typu můžou být velké a když se metody volají v těsné smyčce nebo kritické cesty kódu, náklady na kopírování těchto struktur jsou podstatné. Metody deklarují in parametry, které určují, že argumenty lze bezpečně předat odkazem, protože volaná metoda neupravuje stav tohoto argumentu. Předání těchto argumentů odkazem zabrání (potenciálně) nákladné kopii. Modifikátor explicitně přidáte in na web volání, abyste zajistili, že argument bude předán odkazem, nikoli hodnotou. Explicitní použití in má následující dva efekty:

  • Zadání in v lokalitě volání vynutí kompilátor vybrat metodu definovanou s odpovídajícím in parametrem. V opačném případě, pokud se dvě metody liší pouze v přítomnosti in, podle přetížení hodnoty je lepší shoda.
  • Zadáním deklarujete insvůj záměr předat argument odkazem. Argument použitý s in musí představovat umístění, na které lze přímo odkazovat. Platí stejná obecná pravidla a outref argumenty: Nemůžete použít konstanty, běžné vlastnosti ani jiné výrazy, které vytvářejí hodnoty. Jinak vynechání in v lokalitě volání informuje kompilátor, že je v pořádku vytvořit dočasnou proměnnou, která bude předávat odkazem jen pro čtení do metody. Kompilátor vytvoří dočasnou proměnnou pro překonání několika omezení pomocí in argumentů:
    • Dočasná proměnná umožňuje konstanty v době kompilace jako in parametry.
    • Dočasná proměnná umožňuje pro parametry vlastnosti nebo jiné výrazy in .
    • Dočasná proměnná umožňuje argumenty, ve kterých je implicitní převod typu argumentu na typ parametru.

Ve všech předchozích instancích kompilátor vytvoří dočasnou proměnnou, která ukládá hodnotu konstanty, vlastnosti nebo jiného výrazu.

Následující kód ilustruje tato pravidla:

static void Method(in int argument)
{
    // implementation removed
}

Method(5); // OK, temporary variable created.
Method(5L); // CS1503: no implicit conversion from long to int
short s = 0;
Method(s); // OK, temporary int created with the value 0
Method(in s); // CS1503: cannot convert from in short to in int
int i = 42;
Method(i); // passed by readonly reference
Method(in i); // passed by readonly reference, explicitly using `in`

Předpokládejme, že byla k dispozici jiná metoda používající argumenty podle hodnoty. Výsledky se změní, jak je znázorněno v následujícím kódu:

static void Method(int argument)
{
    // implementation removed
}

static void Method(in int argument)
{
    // implementation removed
}

Method(5); // Calls overload passed by value
Method(5L); // CS1503: no implicit conversion from long to int
short s = 0;
Method(s); // Calls overload passed by value.
Method(in s); // CS1503: cannot convert from in short to in int
int i = 42;
Method(i); // Calls overload passed by value
Method(in i); // passed by readonly reference, explicitly using `in`

Jediným voláním metody, kde je argument předán odkazem, je poslední volání.

Poznámka:

Předchozí kód se používá int jako typ argumentu pro jednoduchost. Vzhledem k tomu int , že není větší než odkaz ve většině moderních počítačů, neexistuje žádný přínos předání jediného int odkazu jako odkazu jen pro čtení.

params modifikátor

Za klíčovým slovem v deklaraci metody nejsou povoleny params žádné další parametry a v deklaraci metody je povoleno pouze jedno params klíčové slovo.

Deklarovaný typ parametru params musí být typ kolekce. Rozpoznané typy kolekcí jsou:

Před jazykem C# 13 musí být parametr jednorozměrným polem.

Při volání metody s parametrem params můžete předat:

  • Čárkami oddělený seznam argumentů typu prvků pole.
  • Kolekce argumentů zadaného typu.
  • Žádné argumenty. Pokud neodešlete žádné argumenty, délka params seznamu je nula.

Následující příklad ukazuje různé způsoby, jak lze argumenty odeslat do parametru params .

public static void ParamsModifierExample(params int[] list)
{
    for (int i = 0; i < list.Length; i++)
    {
        System.Console.Write(list[i] + " ");
    }
    System.Console.WriteLine();
}

public static void ParamsModifierObjectExample(params object[] list)
{
    for (int i = 0; i < list.Length; i++)
    {
        System.Console.Write(list[i] + " ");
    }
    System.Console.WriteLine();
}

public static void TryParamsCalls()
{
    // You can send a comma-separated list of arguments of the
    // specified type.
    ParamsModifierExample(1, 2, 3, 4);
    ParamsModifierObjectExample(1, 'a', "test");

    // A params parameter accepts zero or more arguments.
    // The following calling statement displays only a blank line.
    ParamsModifierObjectExample();

    // An array argument can be passed, as long as the array
    // type matches the parameter type of the method being called.
    int[] myIntArray = { 5, 6, 7, 8, 9 };
    ParamsModifierExample(myIntArray);

    object[] myObjArray = { 2, 'b', "test", "again" };
    ParamsModifierObjectExample(myObjArray);

    // The following call causes a compiler error because the object
    // array cannot be converted into an integer array.
    //ParamsModifierExample(myObjArray);

    // The following call does not cause an error, but the entire
    // integer array becomes the first element of the params array.
    ParamsModifierObjectExample(myIntArray);
}
/*
Output:
    1 2 3 4
    1 a test

    5 6 7 8 9
    2 b test again
    System.Int32[]
*/

Řešení přetížení může způsobit nejednoznačnost, pokud je argument parametru params typem kolekce. Typ kolekce argumentu musí být konvertibilní na typ kolekce parametru. Pokud různé přetížení poskytují lepší převody pro tento parametr, může být tato metoda lepší. Pokud je však argument parametru params buď diskrétní prvky, nebo chybí, jsou všechna přetížení s různými params typy parametrů stejná pro tento parametr.

Další informace najdete v části Seznam argumentů ve Specifikaci jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.