확장 방법 및 동적 개체


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.