2010-05-14 8 views
5

Func object은 일반적인 메서드를 참조 할 수 있습니다. LINQ와 같은 OrderBy :일반 메서드의 경우 C# : Func <T, TResult>

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source, 
    Func<TSource, TKey> keySelector 
) 
+0

어떻게 사용할 지에 대한 샘플을 게시 할 수 있습니까? 나는 당신이 묘사에서 성취하고자하는 것을 정확히 분명히 밝히지 않았다고 생각합니다. – eglasius

답변

19

정확하게 이해한다면 익명의 방법으로 일반적인 방법을 참조 할 수 있는지 묻는 것입니다.

대답은 '예'입니다.

예를 들어 IEnumerable<int> 개체의 요소를 정렬 된 순서로 반환하는 일부 Func (정확히 OrderBy<int, int>)을 원한다고 가정 해보십시오. 이 작업을 수행 할 수 있습니다 :

Func<IEnumerable<int>, Func<int, int>, IOrderedEnumerable<int>> orderByFunc = 
    System.Linq.Enumerable.OrderBy<int, int>; 

은 그럼 그냥 같이이 Func를 사용할 수있는 다른 :

int[] ints = new int[] { 1, 3, 5, 4, 7, 2, 6, 9, 8 }; 

// here you're really calling OrderBy<int, int> -- 
// you've just stored its address in a variable of type Func<...> 
foreach (int i in orderByFunc(ints, x => x)) 
    Console.WriteLine(i); 

출력 : 한편

1 
2 
3 
4 
5 
6 
7 
8 
9 

, 당신은 여부를 묻는하는 경우 다음과 같이 "일반 익명 메소드"를 만들 수 있습니다.

Func<T> getDefault<T> =() => default(T); 

그러면 상황에 따라 다릅니다. 이것은 T이 제네릭 형식 매개 변수로 - 즉 제네릭 클래스 또는 제네릭 메서드 내에서 이미 선언 된 컨텍스트 내에서 수행 할 수 있습니다. (프레디 리오스의 답변을보십시오.) 그러한 상황 밖에서 불행히도 불법입니다.

+1

Dan 감사합니다! 좋은 대답 +1. 일반적인'Func' 객체를 정의 할 수 없다는 뜻입니까? : O – SDReyes

+2

@SDReyes : 범위 내에서 정의 된'T'가 있는지 여부에 달려 있습니다. 즉, 예를 들어 일반 클래스 내에서 작업하는 경우 해당 클래스의 메서드 내에서 'Func '을 선언 할 수 있습니다. 일반적인 방법으로 이것을 할 수도 있습니다. 그러나 아직 일반 적이 지 않은 (즉, 일부 비 제네릭 클래스에 속하는 일반 바닐라 비 제네릭 메서드 내에서) 일반적인 익명 메서드를 선언하는 것은 가능하지 않습니다. –

+0

고마워요 댄 :) – SDReyes

0

다음과 같은 것이 있습니까? 성공적으로 컴파일하고, 당신이 null 허용에 소요 된 문자열을 반환에 대한 기능을 할당 할 수

Func<Nullable<int>, string> myFunc = c => c.HasValue ? c.ToString() : "null";

.

+0

안녕 CubanX!,별로 없습니다. 당신은 nullable 객체를 취하고 문자열을 반환하는 lambda를 참조하고 있습니다. (예를 들어, 형식 TSource받습니다) 제네릭 메서드를 참조하려면 노력하고있어. 많이 고마워요! – SDReyes

0

네, 그것은 가능하지만 짓을

0

당신은

class myClass 
{ 
    T returnsT<T>() 
    {...} 
} 

가이 유형의 인수없이 작동하지 않습니다 어디 형식 인수 (들)

func<int> f = myClass.returnsT<int>; 

를 지정해야합니다 다음과 같은 내용 :

public static class Helper{ 

public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection Form) 
     { 
      return Form.AllKeys.Cast<string>() 
       .Select(key => new KeyValuePair<string, string>(key, Form[key])); 
     } 
} 

이 메서드는 C# 웹 개발의 request.form에 대한 확장 메서드가되었습니다.

+0

안녕하세요, 귀하의 답변에 감사드립니다. 그럼에도 불구하고 이것은 일반적인 방법이 아닙니다. 다시 감사합니다 – SDReyes

4

네,하지만 컨텍스트에 따라 다릅니다. 이미 제네릭으로 작업하고 있다면 컨텍스트에서 T를 사용하십시오. 그렇지 않은 경우 특정 유형을 이미 알고 있습니다. 나중에, 메소드에 약간의 로직을 재사용해야한다면, 아마 메소드로 옮기는 것이 도움이 될 것입니다. 따라서 아래의 두 번째 예제와 같이하십시오.

2 샘플 :

public T Something<T>() { 
    Func<T> someFunc =() => { return default(T); }; 
    return someFunc(); 
} 

public Func<T> GetDefaultCreator<T>() { 
    return() => { return default(T); }; 
} 
+0

프레디 정말 고마워요 +1 – SDReyes

0

나는 그것을 얻을 생각 : 함수 static TResult DoSomeStuff<T, TResult>(T obj)을 감안할 때, 당신이 기준의 창조에 주어진 어떤 형식 매개 변수와 함께, 위의 함수를 참조 것이라는 Func<T, TResult> 등을 만들 수 있습니다 그것에.
나는이 (당신은 내가 순간에 나를 근처에 C 번호가없는, 그것을 테스트 환영합니다) 일 수 있다고 생각 :

class UselessClass<T, TResult> 
{ 
    // If it's a static method, this is fine: 
    public Func<T, TResult> DaFunc = RelevantClass.DoSomeStuff<T, TResult>; 
    // If not, something like this is needed: 
    public UselessClass(SomeClassWhereTheFunctionIs from) 
    { 
     DaFunc = from.DoSomeStuff<T, TResult>; 
    } 
} 

또한,있는 OrderBy에, 실제로 일반적인 위임 아니다. 이것은 변수의 선언입니다. 함수가 주어질 때, 타입은 그것에 유추된다.

관련 문제