static void Main() { C obj = new C("ABC"); // StringSupplier f1 = () => obj.ToString(); // Anonymous method, Lambda StringSupplier f2 = obj.ToString; // Method Reference <=> Java> obj::ToString StringSupplier f3 = new StringSupplier(obj.ToString); StringSupplier f4 = App.Foo; // ldnull + ldftn App:: Foo + newobj StringSupplier Bar(obj.Equals); // ldloc0 + ldvirtftn C::Equals + newobj Predicate + call App::Bar string s1 = f2.Invoke(); string s2 = f2(); // <=> f2.Invoke() }
static void Main() { C obj = new C("ABC"); // StringSupplier f1 = App.Foo; // ldnull + ldftn App:: Foo + newobj StringSupplier /** * Is there any difference in IL from the compilation of f1 and f2 assignment? * R: yes * Which instruction is different? * f1: ldftn App/'<>c__DisplayClass2_0'::'<Main>b__0' // anymous method containing the lambda body * f2: ldvirtftn Object::ToString() */ StringSupplier f1 = () => obj.ToString(); // Anonymous method, Lambda StringSupplier f2 = obj.ToString; // Method Reference <=> Java> obj::ToString // f1() == f2() // f1() two jumps and f2() one jump StringSupplier f3 = new StringSupplier(obj.ToString); // <=> f2 Bar(obj.Equals); // ldloc0 + dup + ldvirtftn C::Equals + newobj Predicate + call App::Bar string s1 = f2.Invoke(); string s2 = f2(); // <=> f2.Invoke() }