확장 방법 및 동적 개체


96

내 문제를 다음 코드 스 니펫으로 요약하겠습니다.

List<int> list = new List<int>() { 5, 56, 2, 4, 63, 2 };
Console.WriteLine(list.First());

위의 코드는 잘 작동합니다.

이제 다음을 시도했습니다.

dynamic dList = list;
 Console.WriteLine(dList.First());

하지만 RuntimeBinderException이 발생하는 이유는 무엇입니까?


이 질문의 중복이 단 4 일 전 질문처럼이 보인다 stackoverflow.com/questions/5270782/...
jbtule

@jbtule 차이점은 this여기에 동적이라는 것입니다.하지만 여기에 착륙하면 아마도 그 질문도 봐야 할 것입니다
nik.shornikov 2012

답변:


131

Stecya의 답변을 확장하려면 ... 확장 메서드는 확장 메서드 형식의 동적 타이핑 의해 지원되지 않습니다 . 즉, 인스턴스 메서드 인 것처럼 호출됩니다. 그러나 이것은 작동합니다.

dynamic dList = list;
Console.WriteLine(Enumerable.First(dList));

물론 유용 할 수도 있고 아닐 수도 있습니다. 동적 타이핑을 사용하려는 이유와 방법에 대한 자세한 정보를 제공해 주시면 더 많은 도움을 드릴 수 있습니다.


동적 객체를 가지고
놀았는데이

19
@geek : 개인적으로 제 경험 법칙은 dynamic정말로 필요한 곳 에서만 사용 하는 것입니다. 기본적으로 성찰을 통해 회원들에게 접근한다면 그것은 큰 징조입니다. 반면에, 저는 엄청나게 정적 인 타이 퍼입니다. 다른 사람들은 덜 비관적 인 정책을 제안 할 수 있습니다. :)
Jon Skeet

2
알고있는 유형으로 다시 캐스팅하는 것이 더 읽기 쉬울 수 있습니다. 이것은 작동합니다. Console.WriteLine (((List <int>) dList) .First ()); 또는 Console.WriteLine ((dList as List <int>). First ()) ;.
AVee

138

Jon의 답변을 확장하기 위해 이것이 작동하지 않는 이유는 일반적인 비 동적 코드 확장 메서드가 일치하는 확장 메서드가있는 정적 클래스에 대해 컴파일러에 알려진 모든 클래스를 전체 검색하여 작동하기 때문입니다. 검색은 네임 스페이스 중첩 및 using각 네임 스페이스에서 사용 가능한 지시문에 따라 순서대로 진행됩니다 .

즉, 동적 확장 메서드 호출을 올바르게 해결하려면 DLR이 런타임에 소스 코드에 있는 모든 네임 스페이스 중첩 및 using지시문 을 알아야 합니다 . 우리는 모든 정보를 호출 사이트에 인코딩하는 편리한 메커니즘이 없습니다. 우리는 그러한 메커니즘을 발명하는 것을 고려했지만 비용이 너무 많이 들고 그만한 가치가없는 일정 위험을 너무 많이 생성했다고 결정했습니다.


설명 해주셔서 감사합니다.
santosh singh 2011

3
바다에 그런 특징이 있습니까? 확실히 획기적인 변화가 될 것입니다. 현재 RunTimeBinderExceptions를 던지는 호출은 소스를 다시 컴파일 할 때 갑자기 작동하기 시작합니다. 또한 그러한 기능을 구현하는 것과 관련된 보안 위험이 있습니까?
Ani

5
@ani : 그 기능을 구현할 계획입니까? 아니요. 보안 위험이 있습니까? 나는 어떤 것도 알지 못한다. 어떤 종류의 보안 위험을 염두에 두셨습니까? 공격자는 누구이며 사용자에게 어떤 위협을 가하고 있는지 말하는 것으로 시작하십시오.
Eric Lippert

@EricLippert, 모든 dynamic개체가 C # :과 같다는 것을 이해 했으므로 구분할 DynamicObject방법이 없으며 확장 메서드를에 추가 할 수없는 이유 중 하나입니다. dynamic맞습니까?
Tom Sarduy

좀 더이 대답을 확장하여 "할 때의 라인을 따라 문장을 추가하는 것을 고려 @EricLippert 어떤 매개 변수가 동적이며, 모든 해상도가 런타임까지 연기됩니다". 그것은 당신에게 분명이 중요한 비트가 SO에 다른 곳에서는 찾기 어려운 반면 (참조 stackoverflow.com/questions/48324768 예를 들어)
알렉세이 Levenkov

18

때문에이 First()방법 아니다 List. Linq Extension에 정의되어 있습니다.IEnumerable<>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.