Search
Duplicate
📅

Predicate으로 사용할 객체형 대리자 및 무명 메서드

Category
S/W 엔지니어
Tags
C#
Predicate
C++/CLI
anonymous method
delegate
Created time
2006/11/18
주요 개념은 Passing parameters to predicates 컬럼에서..
List<>::Find() 등의 검색 메서드에서 조건을 지정할 때 사용하는 Predicate<> 타입의 대리자. MSDN에는 인수를 지정할 수 없는 static 함수형 예제만 나와 있는데, 이보다 더 많이 쓰이게 될 형식은 객체형 대리자 및 무명 메서드이다. 다음은 MSDN에 올라온 함수형 predicate 사용법의 예제다.
using System; using System.Drawing; public class Example { public static void Main() { Point[] points = { new Point(100, 200), new Point(150, 250), new Point(250, 375), new Point(275, 395), new Point(295, 450) }; Point first = Array.Find(points, ProductGT10); Console.WriteLine("Found: X = {0}, Y = {1}", first.X, first.Y); } private static bool ProductGT10(Point p) { return (p.X * p.Y > 100000); } }
C#
복사
위 예제 predicate의 비교 구문 중 100000이란 조건을 임의의 수치로 바꾸고자 할 경우, 함수형 Predicate으론 외부 객체를 사용하지 않고서는 해결할 방법이 없다. 바로 이 때가 무명 메서드와 객체형 대리자가 등장할 좋은 시점이다.
다음은 무명 메서드를 이용한 방법이다.
... int cond = 50000; Point first = Array.Find(points, delegate(Point p) { return (p.X * p.Y > cond); } ...
C#
복사
해당 Predicate의 호출자 앞에 조건(int cond = 50000;)을 넣고 아예 Predicate으로 무명 메서드를 박는 방법으로서, 인수를 넘기는 방법을 제공함과 동시에 코딩 오버헤드를 크게 줄이고 있다.
다음은 객체형 Predicate을 이용한 방법이다(C#).
... int cond = 50000; Point first = Array.Find(points, (new IsBigger(cond)).Match); ... ... class IsBigger { int cond; public IsBigger(int cond) { this.cond = cond; } public Predicate<Point> Match { get { return IsMatch; } } bool IsMatch(Point p) { return (p.X * p.Y > this.cond); } }
C#
복사
익명 메서드와 동일한 효과를 내지만 코딩 오버헤드가 크다는 것이 단점인데, 많이 쓰이게 될 경우에는 객체형 Predicate이 더 효율적이겠다. 하지만 C++/CLI에서는 익명 메서드를 지원하지 않으므로 객체형 Predicate 외에는 선택의 여지가 없다.
다음은 위 코드에 대한 C++/CLI 코드..
... int cond = 50000; Point first = Array::Find(points, (gcnew IsBigger(cond))->Match); ... ... ref class IsBigger { int cond_; public: IsBigger(int cond) { cond_ = cond; } property Predicate<Point>^ Match { Predicate<Point>^ get() { return gcnew Predicate<Point>(this, &IsBigger::IsMatch); } } private: bool IsMatch(Point p) { return (p.X * p.Y > cond_); } };
C#
복사
C++/CLI에서는 함수에 대한 대리자 직접 변환을 지원 안하기 때문에 Predicate<>대리자를 직접 호출해야 한다는 점이 눈에 뜬다. C++/CLI의 특수성으로 인해 C#코드보다 지저분한 것이 사실이다.