// Copyright (c) AlphaSierraPapa for the SharpDevelop Team // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software // without restriction, including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons // to whom the Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all copies or // substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. using System; using System.Collections.Generic; using System.Linq; public static class DelegateConstruction { class InstanceTests { public Action CaptureOfThis() { return delegate { CaptureOfThis(); }; } public Action CaptureOfThisAndParameter(int a) { return delegate { CaptureOfThisAndParameter(a); }; } public Action CaptureOfThisAndParameterInForEach(int a) { foreach (int item in Enumerable.Empty()) { if (item > 0) { return delegate { CaptureOfThisAndParameter(item + a); }; } } return null; } public Action CaptureOfThisAndParameterInForEachWithItemCopy(int a) { foreach (int item in Enumerable.Empty()) { int copyOfItem = item; if (item > 0) { return delegate { CaptureOfThisAndParameter(item + a + copyOfItem); }; } } return null; } public void LambdaInForLoop() { for (int i = 0; i < 100000; i++) { Bar(() => Foo()); } } public int Foo() { return 0; } public void Bar(Func f) { } } public static void Test(this string a) { } public static Action ExtensionMethodUnbound() { return new Action(DelegateConstruction.Test); } public static Action ExtensionMethodBound() { return new Action("abc".Test); } public static Action ExtensionMethodBoundOnNull() { return new Action(((string)null).Test); } public static object StaticMethod() { return new Func(DelegateConstruction.ExtensionMethodBound); } public static object InstanceMethod() { return new Func("hello".ToUpper); } public static object InstanceMethodOnNull() { return new Func(((string)null).ToUpper); } public static List> AnonymousMethodStoreWithinLoop() { List> list = new List>(); for (int i = 0; i < 10; i++) { int counter; list.Add(delegate(int x) { counter = x; } ); } return list; } public static List> AnonymousMethodStoreOutsideLoop() { List> list = new List>(); int counter; for (int i = 0; i < 10; i++) { list.Add(delegate(int x) { counter = x; } ); } return list; } public static Action StaticAnonymousMethodNoClosure() { return delegate { Console.WriteLine(); }; } public static void NameConflict() { // i is captured variable, // j is parameter in anonymous method // k is local in anonymous method, // l is local in main method // Ensure that the decompiler doesn't introduce name conflicts List> list = new List>(); for (int l = 0; l < 10; l++) { int i; for (i = 0; i < 10; i++) { list.Add( delegate (int j) { for (int k = 0; k < i; k += j) { Console.WriteLine(); } }); } } } public static void NameConflict2(int j) { List> list = new List>(); for (int k = 0; k < 10; k++) { list.Add( delegate(int i) { Console.WriteLine(i); }); } } public static Action NameConflict3(int i) { return delegate(int j) { for (int k = 0; k < j; k++) { Console.WriteLine(k); } }; } public static Func> CurriedAddition(int a) { return b => c => a + b + c; } public static Func>> CurriedAddition2(int a) { return b => c => d => a + b + c + d; } }