728x90
반응형
- Delegates
- Anonymous functions (Anonymous methods & Lambda expressions)
Delegates
class Program
{
//Delegate defines the signature (return type and parameters)
delegate void ArithmeticOperation(double operand1, double operand2);
static void Addition(double number1, double number2)
{
Console.WriteLine($"{number1} + {number2} = {number1 + number2}");
}
public static int RunAnotherMethod(ArithmeticOperation theMethod, double operand1, double operand2)
{
return theMethod(a, b);
}
static void Main(string[] args)
{
//Create an instance of the delegate
ArithmeticOperation sum = Addition;
sum(10, 5);
//Pass a delegate method as a variable
RunAnotherMethod(sum, 10, 5)
}
}
델리게이트는 parameter와 return type과 함께 method의 참조를 나타낸다.
- parameter처럼 사용될 수 있다.
- reference type이며, method의 참조를 나타낸다.
- System.Delegate
- delegate instance를 통해 함수 호출된다.
Multicast delegate
+, - operator로 함수를 추가하거나 삭제할 수 있다.
- System.MulticastDelegate
Delegate의 발전
C# 1.0 delegate instance 생성
C# 2.0 anonymous method (inline statement blocks)
C# 3.0 lambda expressions (anonymous method와 비슷하나, 더 표현적이고 간결하다.)
Anonymous method
무명함수. delegate( ) { }
delegate를 return한다.
class Program
{
public static int RunAnotherMethod(Action<double,double> theMethod, double operand1, double operand2)
{
return theMethod(a, b);
}
static void Main(string[] args)
{
// Anonymous method is a delegate() {} and it returns a delegate
Action<double,double> sum = delegate (double number1, double number2)
{
Console.WriteLine($"{number1} + {number2} = {number1 + number2}");
};
sum(10, 5);
RunAnotherMethod(sum, 10, 5);
}
}
Lambda Expressions
object로 취급되는 code block이다.
delegate, expression tree type을 만들 수 있는 짧은 형태의 무명함수이다.
1) expression
class Program
{
public static int RunAnotherMethod(Action<double,double> theMethod, double operand1, double operand2)
{
return theMethod(a, b);
}
static void Main(string[] args)
{
// Lambda expressions are anything with => and a left/right value
// They can return a delegate (so a method that can be invoked)
// or an Expression of a delegate (so it can be compiled and then executed)
Action<double,double> sum = (number1, number2) => Console.WriteLine($"{number1} + {number2} = {number1 + number2}");
sum(10, 5);
RunAnotherMethod(sum, 10, 5);
}
}
2) statement block
Action<double,double> sum = (number1, number2) => {
Console.WriteLine($"{number1} + {number2} = {number1 + number2}");
};
sum(10, 5);
3) Expression of a delegate
Expression<Action<double,double>> sum = (number1, number2) => {
Console.WriteLine($"{number1} + {number2} = {number1 + number2}");
};
sum.Compile().Invoke(10, 5);
LINQ query에서 사용될 수 있다.
Another Example
public static class Helpers
{
// extension method
public static string GetFirstOrDefault(this List<string> items, Func<string, bool> findMatch)
{
foreach (var item in items)
{
if (findMatch(item))
return item;
}
return null;
}
// extension method generic version
public static TResult GetFirstOrDefaultGeneric<TResult>(this List<TResult> items, Func<TResult, bool> findMatch)
{
foreach (var item in items)
{
if (findMatch(item))
return item;
}
return default(TResult);
}
}
class Program
{
public delegate int Manipulate(int a);
public static int NormalMethod(int a)
{
return a * 2;
}
public static int RunAnotherMethod(Manipulate theMethod, int a)
{
return theMethod(a);
}
public static int RunAnotherMethod(Func<int, int> theMethod, int a)
{
return theMethod(a);
}
static void Main(string[] args)
{
var normalMethodInvokeResult = NormalMethod(2);
Manipulate normalMethodDelegate = new Manipulate(NormalMethod);
int normalResult = normalMethodDelegate(3);
int anotherResult = RunAnotherMethod(normalMethodDelegate, 4);
Manipulate anonymousMethodDelegate = delegate (int a)
{
return a * 2;
};
int anonymousResult = anonymousMethodDelegate(3);
int anotherResult2 = RunAnotherMethod(anonymousMethodDelegate, 4);
Manipulate lambdaDelegate = (a) => a * 2;
int lambdaResult = lambdaDelegate(3);
int anotherResult3 = RunAnotherMethod(lambdaDelegate, 4);
// Lambda can return Expression
Expression<Manipulate> expressionLambda = a => a * 2;
// A Func is a delegate with a return type
// Replace Manipulate with a Func
Func<int, int> funcDelegate = (a) => { return lambdaDelegate(a); };
Func<int, int> func2Delegate = (a) => { return a * 2; };
// Mimic the FirstOrDefault Linq expression
var items = new List<string>(new[] { "a", "b", "c", "d", "e", "f", "g" });
var itemInts = Enumerable.Range(0, 10).ToList();
Func<string, bool> aa = item => { return item == "a"; };
Func<int, bool> bb = itemInts => { return itemInts > 4; };
// Calling the build in Linq FirstOrDefault
var foundItem = items.FirstOrDefault(aa);
var foundItemInt = itemInts.FirstOrDefault(bb);
// Calling our version
var foundItem2 = items.GetFirstOrDefault(aa);
var foundItem3 = items.GetFirstOrDefaultGeneric<string>(aa);
var foundItemInt3 = itemInts.GetFirstOrDefaultGeneric<int>(bb);
}
}
728x90
반응형
'C#' 카테고리의 다른 글
C#] LINQ - Projection (0) | 2022.07.20 |
---|---|
C#] 반복자(Iterator), yield keyword (0) | 2022.07.19 |
C#] DynamicObject Class VS ExpandoObject Class (0) | 2022.07.07 |
C#] Expression trees 설명, Delegate와 차이점 (0) | 2022.07.06 |
C#] Delegates (0) | 2022.07.06 |
댓글