확실히 Func
특정 대리자 대신 사용하는 실제 이유 는 C #이 별도로 선언 된 대리자를 완전히 다른 유형으로 취급하기 때문입니다.
비록 Func<int, bool>
와 Predicate<int>
모두 동일한 인수 및 반환 유형이, 그들은 할당 호환되지 않습니다. 따라서 모든 라이브러리가 각 델리게이트 패턴에 대해 고유 한 델리게이트 유형을 선언 한 경우 사용자가 "브리지"델리게이트를 삽입하여 변환을 수행하지 않으면 해당 라이브러리는 상호 운용 할 수 없습니다.
// declare two delegate types, completely identical but different names:
public delegate void ExceptionHandler1(Exception x);
public delegate void ExceptionHandler2(Exception x);
// a method that is compatible with either of them:
public static void MyExceptionHandler(Exception x)
{
Console.WriteLine(x.Message);
}
static void Main(string[] args)
{
// can assign any method having the right pattern
ExceptionHandler1 x1 = MyExceptionHandler;
// and yet cannot assign a delegate with identical declaration!
ExceptionHandler2 x2 = x1; // error at compile time
}
모든 사용자가 Func를 사용하도록 장려함으로써 Microsoft는 이것이 호환되지 않는 대리자 유형의 문제를 완화하기를 희망합니다. 모든 대의원은 매개 변수 / 반환 유형에 따라 일치하기 때문에 잘 어울립니다.
Func
(및 Action
)이 out
또는 ref
매개 변수를 가질 수 없기 때문에 모든 문제를 해결하지는 못하지만 덜 일반적으로 사용됩니다.
업데이트 : 의견 Svish는 말합니다 :
그럼에도 불구하고 매개 변수 유형을 Func에서 Predicate로 또는 그 반대로 전환해도 아무런 차이가없는 것 같습니다. 적어도 문제없이 컴파일됩니다.
예, 프로그램이 내 Main
함수 의 첫 번째 줄에서와 같이 대리자에게만 메서드를 할당하는 한 . 컴파일러는 메소드로 전달하는 델리게이트 오브젝트를 새로 작성하기 위해 자동으로 코드를 생성합니다. 그래서 내 Main
기능에서 문제를 일으키지 않고 x1
유형으로 변경할 수 있습니다 ExceptionHandler2
.
그러나 두 번째 줄에서 첫 번째 대리인을 다른 대리인에게 할당하려고합니다. 두 번째 델리게이트 유형이 정확히 동일한 매개 변수 및 반환 유형을 가지고 있다고 생각하더라도 컴파일러는 error를 제공합니다 CS0029: Cannot implicitly convert type 'ExceptionHandler1' to 'ExceptionHandler2'
.
아마도 이것이 더 명확해질 것입니다 :
public static bool IsNegative(int x)
{
return x < 0;
}
static void Main(string[] args)
{
Predicate<int> p = IsNegative;
Func<int, bool> f = IsNegative;
p = f; // Not allowed
}
내 방법 IsNegative
은 직접 수행 하는 한 p
및 f
변수 에 할당하는 것이 가장 좋습니다 . 그러나 그런 변수 중 하나를 다른 변수에 할당 할 수 없습니다.