Linq의 .Select ()를 사용하면 IEnumerable을 반환하는 이유는 무엇입니까? 유형이 명확하게 정의 되었더라도?

casting dapper dynamic linq

문제

Dapper를 사용하여 동적 객체를 반환하고 때로는 수동으로 매핑합니다. 모든 것이 잘 작동하고 있지만, 캐스팅의 법칙이 무엇인지, 그리고 다음 예가 사실 인 이유가 궁금합니다.

(이 예제의 경우 'StringBuilder'를 알려진 유형으로 사용했지만 일반적으로 'Product'와 비슷합니다.)

예제 1 : 'makeStringBuilder'가 StringBuilder 객체를 명확하게 반환하더라도 IEnumerable<dynamic> 반환하는 이유는 무엇입니까?

Example2 : IEnumerable<StringBuilder> 경우이 코드가 빌드되는 이유는 무엇입니까?

Example3 : Example2와 같은 질문이 있습니까?

private void test()
    {
        List<dynamic> dynamicObjects = {Some list of dynamic objects};

        IEnumerable<dynamic> example1 = dynamicObjects.Select(s => makeStringBuilder(s));

        IEnumerable<StringBuilder> example2 = dynamicObjects.Select(s => (StringBuilder)makeStringBuilder(s));

        IEnumerable<StringBuilder> example3 = dynamicObjects.Select(s => makeStringBuilder(s)).Cast<StringBuilder>();

    }

    private StringBuilder makeStringBuilder(dynamic s)
    {
        return new StringBuilder(s);
    }

위의 예제를 사용하여 이것을 처리하는 권장 방법이 있습니까? 이 상처를 입는 것처럼 캐스팅합니까? 감사!

수락 된 답변

dynamic 인 경우 매개 변수로 사용 dynamic 경우에도 전체 표현식은 동적 바인딩을 통해 처리되므로 컴파일 타임에 (런타임 유형을 기반으로하므로) "동적"이됩니다. 이 내용은 C # 사양의 7.2.2에서 다룹니다.

그러나 표현식이 동적 표현식이면 (즉, 유형이 동적 인 경우), 이는 참여하는 모든 바인딩이 런타임 유형 (즉, 런타임에 표시되는 객체의 실제 유형)을 기반으로해야 함을 나타냅니다 그것이 컴파일 타임에 가지고있는 타입보다. 따라서 이러한 작업의 바인딩은 프로그램 실행 중에 작업이 실행될 때까지 연기됩니다. 이를 동적 바인딩이라고합니다.

귀하의 경우 캐스트를 사용하면이 값을 IEnumerable<StringBuilder> 로 안전하게 변환하고 성능에 거의 영향을 미치지 않습니다. example2 버전은 example3 버전보다 약간 더 효율적이지만이 방법으로 사용하면 오버 헤드가 거의 없습니다.


인기 답변

"왜"에 대해 잘 말할 수는 없지만 example1을 다음과 같이 작성할 수 있어야한다고 생각합니다.

IEnumerable<StringBuilder> example1 = dynamicObjects.Select<dynamic, StringBuilder>(s => makeStringBuilder(s));

컴파일러에게 어떤 유형의 프로젝션을 사용해야하는지 알려줄 필요가 있습니다. 그러나 다른 사람이 올바른 타입을 추론 할 수없는 이유를 분명히 할 수 있습니다. 하지만 투영 유형을 지정하면 실제로 캐스팅하지 않아도되므로 성능상의 이점이 있습니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.