'lamda expression'에 해당되는 글 3건

  1. 2010.06.29 Delegate Variance(대리자 가변성)
  2. 2009.12.23 Lamda Expression - Func&Action
  3. 2009.12.23 Lamda Expression - Introduce

// Type T is declared covariant by using the out keyword.
public delegate T SampleGenericDelegate <out T>();

public static void Test()
{
    SampleGenericDelegate <String> dString = () => " ";

    // You can assign delegates to each other,
    // because the type T is declared covariant.
    SampleGenericDelegate <Object> dObject = dString;          
}


T앞에 out 키워드가 있음을 주목해야 한다. 암시적 형변환을 위해 out 이나 in 키워드를 꼭 써줘야 한다고 한다.
여기서는 스트링이 return 형이니까(파라미터가 아니라...) out  으로 한다.


아래코드는 out 키워드 없이 람다식으로 델리게이트 인스턴스를 만들수 있지만, 대리자간 서로 할당이 안된는 경우를 보여준다.

public delegate T SampleGenericDelegate<T>();

public static void Test()
{
    SampleGenericDelegate<String> dString = () => " ";

    // You can assign the dObject delegate
    // to the same lambda expression as dString delegate
    // because of the variance support for
    // matching method signatures with delegate types.
    SampleGenericDelegate<Object> dObject = () => " ";

    // The following statement generates a compiler error
    // because the generic type T is not marked as covariant.
    // SampleGenericDelegate <Object> dObject = dString;



}

위의 코드를 한참 쳐다 봤다.
이게 왠 암호인가...


public delegate T SampleGenericDelegate<T>();

델리게이트를 정의한다. T 는 제너릭을 뜻할 것이다. 즉 T 는 선언할때 결정되고 이 결정된 형식과 일치하는 시그니처를 갖는 메소드는 이 델리게이트가 다 대리자역할을 할 수 있다.



public string GetString()
{

   return "aaa";
}

라는 메소드가 있다면,

SampleGenericDelegate<String> dString  = GetString;

dString();

이렇게 쓸 수 있다.

그런데 뒤에 () => ""  이건 뭔가...
한 참 째려보니...람다식이다.
http://steelleg.tistory.com/entry/Lamda-Expression 이 글에서 한번 정리했던 건데....그동안 닷넷2.0만 하다보니
다 까먹었다.
=> 왼쪽이 입력 , 오른쪽이 출력 되겠다.
즉 입력 파라미터는 없고, 출력으로 " " 스트링을 내보내는 함수를 정의 한거다.


참고로 Action 과 Func 를 사용하는 경우도 링크해 둔다.
http://msdn.microsoft.com/ko-kr/library/dd465122.aspx
신고

'DotNet > C# 문법' 카테고리의 다른 글

Delegate Variance(대리자 가변성)  (0) 2010.06.29
Anonimous Function  (0) 2009.12.23
Lamda Expression - Func&Action  (0) 2009.12.23
Lamda Expression - Introduce  (0) 2009.12.23
checked & unchecked 키워드  (0) 2009.12.22

댓글을 달아 주세요

http://steelleg.tistory.com/entry/Lamda-Expression 에서 이어지는 내용..

Func 제너릭 델리게이트를 사용한 람다식은 코드량을 많이 줄여준다.

// Code 1
// Generic Lambda Expression Usage
Func<int, int> Square = x => x * x;
int result = Square(4);
Console.WriteLine(result); // 16


위의 코드를 보면 Square  가 제너릭 델리게이트 이므로 따로 정의할 필요가 없다.
람다식의 x 의 형은 Func<int,int> 에서 알수있다.
Func 델리게이트의 정의를 보면  Func 는 리턴형식을 갖는 델리게이트가 리턴값의 형은 제일 마지막 파라미터의 형이 된다.
즉 Func<int,int> 는 입력 파라미터로 하나의 int  를 받고 결과 리턴값으로 int 를 리턴하는 형태의 델리게이트다.
람다식은 익명함수의 내부를 표현하고 있다.
이렇게  Func 에 전달되는 형식에 의해 내부 람다식의 형이 결정된다.
함수형 프로그래밍의 3번째 특징을 만족시켜주는 부분이다.

아래의 코드를 보자.

// Code 2
// Generic Lambda Expression Usage
List<int> primes = new List<int>();
List<int> primeCubes = new List<int>();

// adding set of values to primes
primes.Add(2); primes.Add(3); primes.Add(5); primes.Add(7);

// iterate through primes elements and calculate cube and
// add it to primeCubes using Action<int> action
primes.ForEach(x => primeCubes.Add(x * x * x));

foreach (int i in primeCubes)
{
    Console.WriteLine(i);
}


foreach 문에서 Action<T>  익명메소드를 사용했다. 익명메소드를 foreach 의 argument 로 전달하고있다.

// Code 3
// Generic lambda expression usage
// declare a parameterized type XPowerN
Func<int, float, float> XPowerN = null;

// definition
XPowerN = (n, x) =>
    {
        if (n == 0) return 1.0f;
        else return x * XPowerN(n - 1, x);
    };

// using XPowerN in Square & Cube methods
Func<float, float> Square = x => XPowerN(2, x);
Func<float, float> Cube = x => XPowerN(3, x);

Console.WriteLine(Square(5.0f).ToString());
Console.WriteLine(Cube(5.0f).ToString());


Func<int,float,float> 는  int 와 float 두개의 인자를 받아 float 을 리턴하는 델리게이트 형이다.
XPowerN 은 내부를 람다식으로 정의 하고있다.
내부에서 재귀호출을 하고 있음을 주목해야 한다.

위의 코드에서 XPowerN 부분을

// The following code throws "use of unassigned local variable XPowerN" error.
Func<int, float, float> XPowerN = (n, x) =>
{
    if (n == 0) return 1.0f;
    else return x * XPowerN(n - 1, x);
};

위에 처럼 사용할 수 없다는 것을 주의 해야 한다.

Square 와 Cube 처럼 사용하는 것도 눈여겨 볼 필요가 있다.
신고

'DotNet > C# 문법' 카테고리의 다른 글

Delegate Variance(대리자 가변성)  (0) 2010.06.29
Anonimous Function  (0) 2009.12.23
Lamda Expression - Func&Action  (0) 2009.12.23
Lamda Expression - Introduce  (0) 2009.12.23
checked & unchecked 키워드  (0) 2009.12.22

댓글을 달아 주세요

참고 : http://www.codeproject.com/KB/cs/intro_functional_csharp.aspx
        http://www.codeproject.com/KB/cs/intro_functional_csharp2.aspx

C# 은 버전이 올라가면서 함수형 프로그램에서 여러가지 장점들을 도입하고 있다.
델리게이트와 익명메소드 그리고 람바표현식 등이 대표적이다.

함수형 프로그램 참조 내용 more..


우선 델리게이트는 함수 포이터 처럼 쓸수있는 기능이다.

//Code1
delegate
int MathFunc(int x); // delegate type

static void Main(string[] args)
{
    MathFunc mf = Square; // Square is an instance of the delegate MathFunc
    int result = mf(3);
    Console.WriteLine(result); // output: 9
    Console.ReadLine();
}

static int Square(int x) {return x * x;}

위의 코드는 가장 일반적인 델리게이트 사용법이다.

여기서 주목할 것은 MathFunc mf = Square;   이 코드는 사실
MathFunc mf = new MathFunc(Square);
위의 코드를 줄여쓴 것이다. 위의 코드는 C#1.0 방식의 고전 코딩방식이다.

이 델리게이트의 새로운 표현식이 C# 의 함수형 프로그램밍 표현식의 기초가 된다.

-----------------------------------------

익명메소드

위의 코드에서 mf 인스터스에 Square 를 넘기는 것은 어색해 보인다.
C#2.0 에서는 이름이 없는 함수를 정의해서 사용할 수 있는 익명메소드(anonimous method)를 새로 선보였다.
이것은 delegate 키워들 사용해서 바로 함수 바디를 정의하는 것이다.

// Code 2
// Anonymous method
delegate int MathFunc(int x);

static void Main(string[] args)
{
    MathFunc mf = delegate(int x) { return x * x; }; // anonymous method
    int result = mf(3);
    Console.WriteLine(result);
    Console.ReadLine();
}


Code1 에서 Squar 함수를 따로 정의 했던 부분이 사라졌다.

잠시 제너릭에 관해...
제너릭은 c#2.0 에 추가된 것 중 가장 강력하고 유용한 기능이다.
이를 통해 타잎 안정성이 우수해졋으며 형변환에 따른 오버해드가 줄었다.

람다표현식

c#3.0 에 추가된 기능이다.
이 것은 전 버젼에서 delegate 로 정의하던 익명메소드를 보다 쉽게 사용할 수 있게 해준다.
람다 표현식의 자세한 사항은 여기 를 참고 할 것.

// Code 4
// Lambda Expression
delegate int MathFunc(int x); // usual delegate type declaration

static void Main(string[] args)
{
    MathFunc mf = x => return x * x; // lambda expression in place of
    // delegate instance
    int result = mf(3);
    Console.WriteLine(result);
    Console.ReadLine();
}

코드 3과 비교해서 람다식은 인자의 형을 따로 지정할 필요가 없다, 컴파일러가 델리게이트를 보고 그 형을 알아서 지정해 준다. 함수형 프로그래밍의 2번째 특징인 Type Inference 를 만족하고 있다.

코드 4로도 코드가 많이 줄어들긴 했지만 여전히 람다식을 사용하기 위해서 그에 맞는 델리게이트를 매번 정의해줘야 하는 번거로움이 아직 존재한다.

.NetFramework3.5 에서 나온 제너릭 델리게이트가 이 부분을 해소해 준다.
프레임웍에는 미리정의된 두개의 제너릭 델리게이트가 존재하는데, 하나는 Func 이고 하나는 Action 이다.

이 두개의 제너릭 델리게이트를 사용하면 - 이미 정의되어 있으므로 - 따로 델리게이트를 정의할 필요가 없다.
Func 와 Action 의 차이점은 Func 는 리턴값이 존재하는 형식의 델리게이트고 Action 은 void  형식의 델리게이트라는 것 뿐이다.


// Pre-defined Func delegates
delegate TResult Func<T>();
delegate TResult Func<T1,TResult>(T1 arg1);
delegate TResult Func<T1,T2,TResult>(T1 arg1, T2 arg2);
delegate TResult Func<T1,T2,T3,TResult>(T1 arg1, T2 arg2, T3 arg3);
delegate TResult Func<T1,T2,T3,T4,TResult>T1 arg1, T2 arg2, T3 arg3, T4 arg4);

// Pre-defined Action delegates
delegate void Action<T>(T1 arg1);
delegate void Action<T1,T2>(T1 arg1, T2 arg2);
delegate void Action<T1,T2,T3>T1 arg1, T2 arg2, T3 arg3);
delegate void Action<T1,T2,T3,T4>T1 arg1, T2 arg2, T3 arg3, T4 arg4);

이 부분은 다음 글에 설명한다.





 


 

신고

'DotNet > C# 문법' 카테고리의 다른 글

Delegate Variance(대리자 가변성)  (0) 2010.06.29
Anonimous Function  (0) 2009.12.23
Lamda Expression - Func&Action  (0) 2009.12.23
Lamda Expression - Introduce  (0) 2009.12.23
checked & unchecked 키워드  (0) 2009.12.22

댓글을 달아 주세요