IT story

왜 Func인가

hot-time 2020. 5. 5. 19:36
반응형

왜 Func인가 술어 대신?


이것은 누군가 호기심이 많은 질문입니다.

.NET Framework 클래스 라이브러리에는 다음 두 가지 방법이 있습니다.

public static IQueryable<TSource> Where<TSource>(
    this IQueryable<TSource> source,
    Expression<Func<TSource, bool>> predicate
)

public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, bool> predicate
)

Func<TSource, bool>대신에 사용 Predicate<TSource>합니까? 등이 보인다는 Predicate<TSource>전용으로 사용 List<T>하고 Array<T>있는 동안, Func<TSource, bool>거의 모든에 의해 사용되는 QueryableEnumerable방법과 확장 방법이 무엇이야 ...?


반면 Predicate같은 시간에 도입 된 것으로 List<T>하고 Array<T>, .NET 2.0, 다른 FuncAction변형 .NET 3.5에서 왔습니다.

따라서 이러한 Func술어는 주로 LINQ 연산자의 일관성을 위해 사용됩니다. 사용에 대한 .NET 3.5 이후는, Func<T>지침 상태 :Action<T>

새로운 LINQ 유형을 사용하십니까 Func<>하고 Expression<>대신 사용자 대표와 술어의


나는 이것을 전에 궁금했다. 나는 Predicate<T>대의원을 좋아한다 -그것은 훌륭하고 묘사 적이다. 그러나 다음의 과부하를 고려해야합니다 Where.

Where<T>(IEnumerable<T>, Func<T, bool>)
Where<T>(IEnumerable<T>, Func<T, int, bool>)

항목의 색인을 기준으로 필터링 할 수도 있습니다. 훌륭하고 일관된 반면,

Where<T>(IEnumerable<T>, Predicate<T>)
Where<T>(IEnumerable<T>, Func<T, int, bool>)

없을 것입니다.


확실히 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는 말합니다 :

Still, switching a parameter type from Func to Predicate and back, doesn't seem to make any difference? At least it still compiles without any problems.

Yes, as long as your program only assigns methods to delegates, as in the first line of my Main function. The compiler silently generates code to new a delegate object that forwards on to the method. So in my Main function, I could change x1 to be of type ExceptionHandler2 without causing a problem.

However, on the second line I try to assign the first delegate to another delegate. Even thought that 2nd delegate type has exactly the same parameter and return types, the compiler gives error CS0029: Cannot implicitly convert type 'ExceptionHandler1' to 'ExceptionHandler2'.

Maybe this will make it clearer:

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
}

My method IsNegative is a perfectly good thing to assign to the p and f variables, as long as I do so directly. But then I can't assign one of those variables to the other.


The advice (in 3.5 and above) is to use the Action<...> and Func<...> - for the "why?" - one advantage is that "Predicate<T>" is only meaningful if you know what "predicate" means - otherwise you need to look at object-browser (etc) to find the signatute.

Conversely Func<T,bool> follows a standard pattern; I can immediately tell that this is a function that takes a T and returns a bool - don't need to understand any terminology - just apply my truth test.

For "predicate" this might have been OK, but I appreciate the attempt to standardise. It also allows a lot of parity with the related methods in that area.

참고URL : https://stackoverflow.com/questions/665494/why-funct-bool-instead-of-predicatet

반응형