2013-03-29 3 views
6

형식 유추에 대해 조금은 검색했지만 특정 문제에 대한 솔루션을 적용 할 수 없습니다.중첩 된 일반 함수에 대한 유형 유추

저는 건물을 짓고 기능을 전달하는 일을 많이하고 있습니다. 이것은 int 형을 추측 할 수 있어야하는 것처럼 보입니다. 내가 생각할 수있는 유일한 것은 람다 리턴 타입이 타입 추론 알고리즘에 의해 체크되지 않는다는 것입니다. 문제를보다 분명하게 보여주기 위해 불필요한 논리를 제거했습니다.

Func<T> Test<T>(Func<Func<T>> func) 
{ 
    return func(); 
} 

이 컴파일 :

Func<int> x = Test<int>(() => 
    { 
     int i = 0; 
     return() => i; 
    }); 

을하지만,이 오류를 준다 "메서드의 형식 인수는 사용에서 유추 할 수 없습니다 명시 적 형식 인수를 지정하십시오."

Func<int> x = Test(() => 
    { 
     int i = 0; 
     return() => i; 
    }); 

나는 그것이 왜 이런 식으로 작동하는지 그리고 모든 해결 방법을 알고 싶다.

+0

매우 비슷한 질문이지만 완전히 동일하지는 않습니다. http://stackoverflow.com/questions/6090159/inferring-generic-types-with-functional-composition –

답변

7

나는이 질문에 대한 정답은 SO Why can't an anonymous method be assigned to var?

에 E.Lippert에 의해 주어진다라고하지만 우리가 조금 귀하의 예제와 함께 놀자 것 :

Func<Func<int>> f =() => 
{ 
    int i = 0; 
    return() => i; 
}; 

Func<int> x = Test(f); //it compiles OK 

와 형식 유추 없음 문제가 당신의 Func<T> Test<T>(Func<Func<T>> func) 여기에 있습니다. 유추 할 수없는 유형의 익명 람다 식을 사용한다는 점에서이 문제는 숨겨져 있습니다. 이 시도 : 그것은 Compiler Error CS0815을 제공

var f =() => 
{ 
    int i = 0; 
    return() => i; 
}; 

,

암시 형식의 로컬 변수

및 설명을 람다 식을 할당 할 수 없습니다 것은 말 :

을 암시 적으로 형식화 된에 대한 이니셜 라이저로 사용되는 식210 변수에는 유형이 있어야합니다. 익명 함수 식 메서드 그룹 식과 null 리터럴 식은 형식이 없으므로 적절한 초기화 프로그램이 아닙니다. 암시 적으로 형식화 된 변수는 선언에 null 값으로 초기화 할 수 없습니다. 나중에 값을 null로 지정할 수 있습니다.

이제 다른 일을 해보자 : 그것은뿐만 아니라 컴파일

var x = Test(() => 
{ 
    Func<int> f =() => 0; 
    return f; 
}); 

.

return() => i; 

우리는 더 갈 수와 에릭 Lippert의 그의 대답에 말씀에 따라이 포장하는 또 다른 기능을 제공합니다 : 우리는 지금

static Func<T> GetFunc<T>(Func<T> f) { return f; } 

를 그래서 원래 예제의 문제는이 라인 사실이었다 다음과 같이 코드를 다시 작성할 수 있습니다.

var x = Test(() => 
{ 
    int i = 0; 
    return GetFunc(() => i); 
}); 

그리고 잘 작동합니다.

그러나 내가 아는 한이 모든 것이 오버 헤드이며 명시 적 유형을 제공해야합니다. 이러한 해결 방법은 람다가 필요할 때 적합하지만 익명 형식의 개체를 반환합니다.