public void UtilizeDelegate3() { var horror = "test"; AnotherDelegate awesome = s => { Debug.Trace("UtilizeDelegate3 was used!" + s, 0); }; awesome(horror); }
public DelegatesAndEvents() { // add method/delegate to the invocation list DelegateInstance += Method; // or another syntax DelegateInstance += new AnotherDelegate(Method); // remove a method/delegate to the invocation list DelegateInstance -= Method; // or the more formal syntax DelegateInstance -= new AnotherDelegate(Method); // set the invocation list to a single method/delegate DelegateInstance = Method; // or the more formal syntax DelegateInstance = new AnotherDelegate(Method); // to clear a delegate, assign it to null: DelegateInstance = null; // for all the previous operators, its very important to note // that they instantiate a new MulticastDelegate in the process. // this means that every add (+=) or remove(-=) generates a new // MulticastDelegate. Look at the following scenario: DelegateInstance = Method; // invoking a will call Method AnotherDelegate a = DelegateInstance; DelegateInstance += AnotherMethod; // now, invoking a will still only invoke Method, while // invoking DelegateInstance will invoke both Method // and AnotherMethod. // NOTE NOT BEST PRACTICE SEE BELOW a(); // invokes Method DelegateInstance(); // invokes Method and AnotherMethod // The main importance of this fact deals with thread safety // when invoking delegates. When invoking a delegate, you // should always do a null-check before invocation to avoid // an exception: // NOTE NOT BEST PRACTICE SEE BELOW if (a != null) { a(); } // the problem with the above code is that if another thread removes // Method from a, after the null check, trying to invoke a will throw // an exception. To get around this, since we stated before that the // remove operation recreates the MulticastDelegate, assigning the // delegate to a temporary delegate before doing the null check, and // then invoking that temporary delegate should avoid threading problems //************************************************************** // NOTE THIS IS BEST PRACTICE FOR INVOKING A DELEGATE/EVENT // This is thread-safe AnotherDelegate aCopy = a; if (aCopy != null) { aCopy(); } //************************************************************** }
public static int test_0_tests() { // Check that creation of delegates do not runs the class cctor DoIt doit = new DoIt(B.method); // // Beginn Aenderung Test // // if (A.b_cctor_run) // return 1; // // Ende Aenderung Test // Tests test = new Tests(); SimpleDelegate d = new SimpleDelegate(F); SimpleDelegate d1 = new SimpleDelegate(test.VF); NotSimpleDelegate d2 = new NotSimpleDelegate(G); NotSimpleDelegate d3 = new NotSimpleDelegate(test.H); d(); d1(); // we run G() and H() before and after using them as delegates // to be sure we don't corrupt them. G(2); test.H(3); Console.WriteLine(d2(2)); Console.WriteLine(d3(3)); G(2); test.H(3); if (d.Method.Name != "F") { return(1); } if (d3.Method == null) { return(1); } object [] args = { 3 }; Console.WriteLine(d3.DynamicInvoke(args)); AnotherDelegate d4 = new AnotherDelegate(puts); if (d4.Method == null) { return(1); } Console.WriteLine(d4.Method); Console.WriteLine(d4.Method.Name); Console.WriteLine(d4.Method.DeclaringType); return(0); }
public void Delegate_In_Delegate() { var magic = "helloo"; HorribleDelegate awesome = () => { AnotherDelegate awe2 = s => { Debug.Trace("UtilizeDelegate4 was used!" + s, 0); }; awe2(magic); }; awesome(); }
public static int test_0_tests () { // Check that creation of delegates do not runs the class cctor DoIt doit = new DoIt (B.method); if (A.b_cctor_run) return 1; Tests test = new Tests (); SimpleDelegate d = new SimpleDelegate (F); SimpleDelegate d1 = new SimpleDelegate (test.VF); NotSimpleDelegate d2 = new NotSimpleDelegate (G); NotSimpleDelegate d3 = new NotSimpleDelegate (test.H); d (); d1 (); // we run G() and H() before and after using them as delegates // to be sure we don't corrupt them. G (2); test.H (3); Console.WriteLine (d2 (2)); Console.WriteLine (d3 (3)); G (2); test.H (3); if (d.Method.Name != "F") return 1; if (d3.Method == null) return 1; object [] args = {3}; Console.WriteLine (d3.DynamicInvoke (args)); AnotherDelegate d4 = new AnotherDelegate (puts); if (d4.Method == null) return 1; Console.WriteLine (d4.Method); Console.WriteLine (d4.Method.Name); Console.WriteLine (d4.Method.DeclaringType); return 0; }
public static int test_0_tests() { DoIt doit = new DoIt (B.method); if (A.b_cctor_run) return 1; Tests test = new Tests (); SimpleDelegate d = new SimpleDelegate (F); SimpleDelegate d1 = new SimpleDelegate (test.VF); NotSimpleDelegate d2 = new NotSimpleDelegate (G); NotSimpleDelegate d3 = new NotSimpleDelegate (test.H); d (); d1 (); G (2); test.H (3); Console.WriteLine (d2 (2)); Console.WriteLine (d3 (3)); G (2); test.H (3); if (d.Method.Name != "F") return 1; if (d3.Method == null) return 1; object [] args = {3}; Console.WriteLine (d3.DynamicInvoke (args)); AnotherDelegate d4 = new AnotherDelegate (puts); if (d4.Method == null) return 1; Console.WriteLine (d4.Method); Console.WriteLine (d4.Method.Name); Console.WriteLine (d4.Method.DeclaringType); return 0; }
public void Todo() { MyIntBinaryOperationDelegate del = (x, y) => x + y; Console.WriteLine(del(1, 2)); del = Multiply; Console.WriteLine(del(1, 2)); del += Multiply; // MulticastDelegate => we can add more methods, they will be chained Console.WriteLine("Num of methods: {0}", del.GetInvocationList().Count()); del(1, 2); // TODO: implement async call using old-styled pattern // del.BeginInvoke() // del.EndInvoke() AnotherDelegate another = (B b) => new A(); // exact types another = (B b) => new B(); // can return more derived type => covariance another = AnotherMethod; // can use method with less derived parameters => contravariance int n = 5; Func <int, int> multByVar = i => i * n; // n captured by lambda - closure Console.WriteLine(multByVar(5)); var pub1 = new Publisher1(); pub1.OnChange += () => Console.WriteLine("First subscr"); pub1.OnChange += () => Console.WriteLine("Second subscr"); pub1.Raise(); pub1.OnChange = () => Console.WriteLine("First subscr 2"); // direct assignment removes all other subscribers pub1.OnChange(); // as OnChange is just a public field, we can invoke it by explicit call var pub2 = new Publisher2(); pub2.OnChange += () => Console.WriteLine("1"); pub2.OnChange += () => Console.WriteLine("2"); pub2.Raise(); // pub2.OnChange(); - it's event now, not able to invoke it by calling // proper event raise pattern var pub4 = new Publisher4(); pub4.OnChange += Pub4_OnChange; pub4.Raise(); // exception handling var pub6 = new Publisher6(); pub6.OnChange += () => Console.WriteLine(1); pub6.OnChange += () => { throw new Exception("FUUUUUU"); }; pub6.OnChange += () => Console.WriteLine(2); try { pub6.Raise(); } catch (AggregateException agrEx) { Console.WriteLine("Caugth aggregate exception with {0} children", agrEx.InnerExceptions.Count); } }