Metódus paramétere egy metódus c#

Címkék
Metódus paramétere egy metódus c#
2020-11-30T16:28:09+01:00
2020-12-01T18:35:32+01:00
2022-08-11T23:20:54+02:00
Lechu947
Azt meg tudom csinálni, hogy egy metódus paramétere egy metódus legyen?

Pl.
Ez a pár sor sokszor előfordul a programban: 

Console.WriteLine("\nEnter any key!"); Console.ReadKey(); this.ValamiMetodus();
és ezt szeretném kiszervezni egy metódusba, hogy ugye mindig csak az adott metódus, amire ugrik majd, az változna:

public void EnterAnyKey(Metodus metodus) { Console.WriteLine("\nEnter any key!"); Console.ReadKey(); metodus; }
Mutasd a teljes hozzászólást!
Persze. Delegate-et át tudsz adni paraméterként. Az alaprendszer biztosít is jónéhányat, a legegyszerűbb az Action, ami egy paraméter nélküli metódus delegate.

Itt egy példa. Sorban átadja mindkét "Hello" metódust paraméterként.

static void Main(string[] args) { EnterAnyKey(Hello1); EnterAnyKey(Hello2); } public static void EnterAnyKey(Action action) { Console.WriteLine("Enter any key!"); Console.ReadKey(true); action(); } private static void Hello1() { Console.WriteLine("Hello 1"); } private static void Hello2() { Console.WriteLine("Hello 2"); }
Mutasd a teljes hozzászólást!

  • Azta köszi! :)

    De az ugye nem gond, hogy a metódusok, amiket paraméterként megkap, teljesen különbözőek?
    Mármint, ami bennük történik az különböző, de a paraméter számuk és visszatérési értékük mindnek nulla.
    Mutasd a teljes hozzászólást!
  • Szia!
    Nem egészen világos, miért így szeretnéd ezt megoldani. Úgy érzem, fordítva ülsz a lovon. Én így oldanám meg:

    private void Kiiras() { Console.WriteLine("\nEnter any key!"); Console.ReadKey(); } public void Eljarasom() { Kiiras(); this.ValamiMetodus(); }
    Gábor
    Mutasd a teljes hozzászólást!
  • Egyáltalán nem probléma. A lényeg, hogy a szignatúrájuk feleljen meg a várt delegate-nek.
    Vannak egyébként paraméteres Action-ök is egészen 16 paraméterig (pl. Action<T1, T2>), vagy akár használhatsz függvényeket is ha szükséges (pl. Func<T>). Paraméteres esetben nyilván a paraméter(eke)t is át kell adni.

    Itt egy paraméteres példa:

    static void Main(string[] args) { Process(Multiply, 4); Process(Power, 4); } public static void Process(Action<int> action, int parameter) { Console.WriteLine("Enter any key!"); Console.ReadKey(); action(parameter); } private static void Multiply(int parameter) { Console.WriteLine(parameter * 5); } private static void Power(int parameter) { Console.WriteLine(Math.Pow(parameter, 2)); }

    És egy kicsit nehezebben érthető általánosabb megoldás. Ezt csak a lehetőségek bemutatása céljából, mert ebben a formában nem sok gyakorlati haszna van. Ha érdekel hogy mi ez, akkor "c# generic methods" kifejezéssel keresd.

    static void Main(string[] args) { Process(ToInt32, 123.456); Process(ToDecimal, true); } public static void Process<T>(Action<T> action, T parameter) where T : IConvertible { Console.WriteLine("Enter any key!"); Console.ReadKey(); action(parameter); } private static void ToInt32<T>(T parameter) where T : IConvertible { Console.WriteLine(Convert.ToInt32(parameter)); } private static void ToDecimal<T>(T parameter) where T : IConvertible { Console.WriteLine(Convert.ToDecimal(parameter)); }
    Mutasd a teljes hozzászólást!
  • Csak azért így csináltam, mert így 3 sorból lesz 1, a te módszereddel pedig eggyel kevesebb sort spórolok meg.
    Mutasd a teljes hozzászólást!
  • Szia!
    Ha javasolhatok valamit, ezt az elgondolást felejtsd el.
    Azért, hogy spórolj a forráskódban 1-1 sort, bevezetsz egy sokkal nehezebben átlátható, bonyolultabb, valamint futásidőben nagyobb erőforrásokat felhasználó módszert. (Ugyanis az én általam írt megoldás a kódban foglal helyet, míg a metódus átadása a paraméterben már heap-et használ, ennek kezelése pedig plusz erőforrást kíván a futtató környezet részéről).
    Gábor
    Mutasd a teljes hozzászólást!
  • Ja bocsi ezt nem tudtam, de akkor miért van egyáltalán ilyenre lehetőség?
    Mutasd a teljes hozzászólást!
  • Azért, mert vannak olyan szituációk, ami másképp nem oldhatók meg.
    A delegate alapvetően az eseménykezelés kiszolgálásra szolgál.

    Az az elképzelés, hogy rövidebb forráskód hatékonyabb programot fog eredményezni, téves. Az előfordító, illetve a JIT fordító ha lehetséges, úgy is optimalizálni fog. Viszont sokkal nagyobb problémát fogsz okozni magadnak, ha nehezen átlátható kódot készítesz.
    Mutasd a teljes hozzászólást!
  • Köszi, hogy szóltál, így már világos! Átírtam a tiédre :)
    Mutasd a teljes hozzászólást!
  • Új funkcionalitást tudsz adni egy objektumhoz anélkül, hogy a struktúráját megváltoztatnád ("open for extension - close for modification"). Ilyen helyzet például, amikor egy művelet számára át lehet adni egy callback metódust, amit ő bizonyos esemény bekövetkezésekor végrehajt. A Windows API-ban találhatók például ilyenek. Kicsit speciálisabb eset az eseménykezelés (multicast delegate). De létezik például decorator design pattern is, ami szintén megvalósítható így. Szóval ez egy lehetőség, amivel szükség esetén lehet (bizonyos esetekben kell) élni.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
Címkék
abcd