« Delegate » : différence entre les versions
Ligne 80 : | Ligne 80 : | ||
<kode lang='cs'> | <kode lang='cs'> | ||
Expression<Func<int, int>> | Expression<Func<int, int>> multiplyByFiveExpression = num => num * 5; | ||
// compiler une expression donne un delegate | // compiler une expression donne un delegate | ||
Func<int, int> | Func<int, int> multiplyByFiveFunction = multiplyByFiveExpression.Compile(); | ||
// appel | // appel | ||
multiplyByFiveFunction(10); // 50 | |||
Console.WriteLine( | Console.WriteLine(multiplyByFiveExpression); // num => (num * 5) | ||
Console.WriteLine( | Console.WriteLine(multiplyByFiveExpression.Body); // (num * 5) | ||
Console.WriteLine( | Console.WriteLine(multiplyByFiveExpression.Parameters.Count); // 1 | ||
Console.WriteLine( | Console.WriteLine(multiplyByFiveExpression.Parameters[0]); // num | ||
</kode> | </kode> | ||
Version du 13 mars 2021 à 21:28
Definition
Un délégué est un pointeur sur méthode.
delegate
// Définition du délégué correspondant à la signature de la méthode CountLetters delegate int MonDélégué(string inString); int CountLetters(string inString) { return inString.Length; } // Différente manière d'instancier le délégué MonDélégué monDéléguéA = new MonDélégué(CountLetters); // named function // écriture simplifiée MonDélégué monDéléguéA = CountLetters; // anonymous function (C# 2) MonDélégué monDéléguéA = delegate(string inString) { return inString.Length; }; // lambda expression (C# 3) MonDélégué monDéléguéA = (string inString) => { return inString.Length; }; // écriture simplifiée MonDélégué monDéléguéA = inString => inString.Length; // appel du délégué monDéléguéA("1"); |
Func
Signature de délégué générique ayant de 0 à 16 arguments d'entrée et 1 argument de sortie.
Cette signature de délégué générique existe grâce à la covariance (out) et la contra variance (in) des génériques introduit avec C# 4.
// Signatures déjà existantes, à ne pas recopier dans le code public delegate TResult Func<out TResult>(); public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, out TResult> (T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); |
Func<string, int> monDéléguéA = CountLetters; monDéléguéA("1"); Func<string, int> monDéléguéB = delegate(string inString) { return inString.Length; }; monDéléguéB("12"); Func<string, int> monDéléguéC = inString => inString.Length; monDéléguéC("123"); |
Action
Signature de délégué générique ayant de 1 à 16 arguments d'entrée et 0 argument de sortie.
// Signature déjà existante, à ne pas recopier dans le code public delegate void Action<in T>(T obj); // utilisation Action<string> a = inString => Console.WriteLine(inString); a("Ok"); |
Predicate
Signature de délégué générique ayant de 1 argument d'entrée et 1 argument de sortie.
public delegate bool Predicate<in T>(T obj); |
Expression Tree
An expression is a sequence of operands and operators that can be evaluated to a single value.
Expression trees represent code as a tree-like data structure, where each node is an expression.
Expression<Func<int, int>> multiplyByFiveExpression = num => num * 5; // compiler une expression donne un delegate Func<int, int> multiplyByFiveFunction = multiplyByFiveExpression.Compile(); // appel multiplyByFiveFunction(10); // 50 Console.WriteLine(multiplyByFiveExpression); // num => (num * 5) Console.WriteLine(multiplyByFiveExpression.Body); // (num * 5) Console.WriteLine(multiplyByFiveExpression.Parameters.Count); // 1 Console.WriteLine(multiplyByFiveExpression.Parameters[0]); // num |
Multicasting et gestion des exceptions
Si une des méthodes associées à l'event lance une exception, les méethodes associées suivantes ne seront pas exécutées.
delegate void MyDelegate(); MyDelegate a = () => Console.WriteLine("1"); a += () => { Console.WriteLine("2"); throw new Exception("xxx"); }; a += () => Console.WriteLine("3"); var exceptions = new List<Exception>(); // exécute toutes les méthodes et capture les exceptions foreach (Delegate handler in a.GetInvocationList()) { try { handler.DynamicInvoke(); } catch (Exception ex) { exceptions.Add(ex); } } // relance les exceptions if (exceptions.Any()) { throw new AggregateException(exceptions); } |