2016-11-22 4 views
3

.Cast<T> LINQ 확장 방법에 대해 궁금한 점이 몇 번있었습니다. 나는 나 자신에게 "나는이 상황에서 필요한 것처럼 들린다"라고 생각하지만, 그것을 사용하려고 할 때마다 항상 결국 InvalidCaseException이됩니다. 나는이 방법을 성공적으로 사용할 수 없었다. 여기에 예외를 확인하는 예 라인이다 :. 캐스트 <T> 확장 메서드가 항상 throw됩니다. InvalidCastException -이 메서드는 어떻게 사용해야합니까?

Enumerable.Range(0,10).Cast<float>().ForEach(Console.Out.WriteLine); 

거기에 floatint 캐스팅에 대한 논란이 아무것도 없다, 왜이 방법은 그것을 거부합니까? 나는이 문제를 해결하고 단순히 너무 많은 혼전없는 .Select(x => (float)x)

Enumerable.Range(0, 10).Select(x => (float)x).ForEach(Console.Out.WriteLine); 

으로 .Cast<float>를 대체하여 원하는 효과를 얻을 수 있지만, Cast<float> 방법이 할 수없는 이유를 아직도 난 그냥하지 않을 수 있습니다 나를위한 직업.

간단히 말해서 : .Cast<T> 확장 방법을 어떻게 사용합니까?

이 질문에 관련이없는,하지만 누군가가 알고 싶은 경우에, 나는 그 코드에서 사용자 지정에 ForEach 확장 방법은 위의 최대 니펫 (표준 하나는리스트와 함께 작동) 사용 :

static class Extensions 
{ 
    public static void ForEach<T>(this IEnumerable<T> x, Action<T> l) 
    { 
     foreach (var xs in x) l(xs); 
    } 
} 
+4

http://stackoverflow.com/questions/15394032/difference-between-casting-and-using-the-convert-to-method이 링크 좋은 설명을 확인하십시오 당신은 문제의 시도 다음을 모방하려는 경우 –

답변

3

Cast<TResult> 방법의 소스 코드를 ReferenceSource 보면,이 같은 인 CastIterator<TResult> 메서드를 호출 결국이 표시됩니다 보시다시피

static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source) 
{ 
    foreach (object obj in source) yield return (TResult)obj; 
} 

, C#을 TResult으로 캐스팅하려고 박스에서 개체이며 예외의 이유입니다.

int a = 5; 
object o = a; 
float f = (float)o; 
2

다음 쓸 때 :

int a = GetInt(); 
var b = (float)a; 

당신은 실제로하지 않은 값을 캐스팅. 당신이 그것을 바꾸고 있습니다. C#은 멋진 구문을 제공합니다. 여기에서 생성 된 IL은 conv.r4이며 스택의 맨 위에있는 값을 부동 소수점으로 변환합니다.

Enumerable.Cast<T>은 실제로 캐스트를 수행하고 있으며 구문 설탕을 제대로 처리하지 못합니다.

은 당신이 쓰는 것 인 경우 :

Enumerable.Range(0,10).Cast<object>().ForEach(Console.Out.WriteLine); 

당신은 괜찮을 것, 정수 으로 객체 스트입니다.

+2

더 자세한 정보가 필요하다고 생각합니다. 전송과 변환의 차이점은 무엇입니까? 항상 변환 할 수없는 이유는 무엇입니까? 원하는대로 작동하는 Cast 확장 프로그램을 만들 수없는 이유는 무엇입니까 (또는 가능한 경우 어떻게?). – Evk