2009-12-18 3 views
8

예, 제목이 약간 혼란 스럽습니다. 그래서 나는 여러분이 C# 4.0 '동적'개체와 속성 이름을 가지고 있다고 가정 해 설명하겠습니다. 동적 객체에서 그 속성을 어떻게 가져 옵니까?동적 개체에서 동적으로 값 가져 오기

public static object GetDynamicValue(dynamic o, string name) { ... } 

또 다른 방법은 내가 IDictionary 같은 동적 객체를 치료하기 위해 노력하고 있다는 것입니다 넣어 : 당신이 어떻게 구현 될 수 즉

.

동적 객체가 리플렉션 기반이 아닌 맞춤 구현 (예 : DynamicObject 확장 및 자체 작업 수행) 일 수 있으므로 여기에 리플렉션을 사용할 수 없습니다.

+1

InvokeGet를 참조하십시오? IDictionary와 비슷한 동적 객체를 원한다면 ExpandoObject를 사용하지 않을까요? Jon의 제안이 효과가 있을지 모르겠지만이 작업은 사용자가하려는 작업에 대한 너무 복잡한 해결책이라고 생각합니다. –

답변

13

작성, 전화 사이트를 구축해야 바인더 등

어떻게 볼 수있는 가장 쉬운 방법이 컴파일하는 것입니다

: 리플렉터와 함께 컴파일 다음

public static object GetDynamicValue(dynamic o, string name) 
{ 
    return o.Foo; 
} 

및 운동 무엇을 그것은하고있다. 그것은 꽤 복잡 할 것입니다. 그리고 여러분은 그것을 하나의 정적 인 캐시 된 호출 사이트에서 각 호출에 대한 새로운 호출 사이트로 변경해야 할 것입니다. 여기

이 작업을 수행하는 예 ...하지만 그것은 여부 완전히 올바른지 아닌 다른 문제 : (I이 나는 위의 제안을 정확히 수행하여 가고있어.)

using Microsoft.CSharp.RuntimeBinder; 
using System; 
using System.Dynamic; 
using System.Runtime.CompilerServices; 

class Test 
{ 
    public static object GetDynamicValue(dynamic o, string name) 
    { 
     CallSite<Func<CallSite, object, object>> site 
      = CallSite<Func<CallSite, object, object>>.Create 
      (Binder.GetMember(CSharpBinderFlags.None, name, 
      typeof(Test), new CSharpArgumentInfo[] 
      { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) })); 
     return site.Target(site, o); 
    } 

    static void Main() 
    { 
     Console.WriteLine(GetDynamicValue("hello", "Length")); 
    } 
} 
+0

매우 감사합니다. Jon! 그것은 내가 다룰 수 없었던 많은 개념들을 가져다줍니다. 그래서 그것을 신중하게 연구 할 필요가 있습니다. 관련성이 없기 때문에 typeof (Test)가 사용 된 것이 이상합니다. 하지만 null로 설정하려고했는데 코드가 여전히 작동하므로 분명히 많이하지 않았습니다. –

+3

이것은 액세스 할 수있는 멤버와 관련이 있습니다.이 코드를 사용하여 Test의 개인 멤버 만 액세스 할 수 있지만 다른 유형의 비공개 멤버는 액세스 할 수 없습니다. –

3

오픈 소스 프레임 워크 ImpromptuInterface (nuget에서 사용 가능)는 이것을 수행하며 호출 사이트 캐싱이 성능 향상에 중요하기 때문에 추가 작업이 필요합니다.

는 사용 사례에 대해 조금 더 알 수

public static object GetDynamicValue(dynamic o, string name) { 
     return Impromptu.InvokeGet(o,name); 
} 
+0

Clay도 이와 비슷한 일을합니다. (http : //clay.codeplex.com/) –

+0

@ David-Ebbo Clay는 문자열 이름을 통해 자체 속성에 액세스 할 수 있지만 InvokeGet을 사용하면 문자열 이름을 통해 모든 IDynamicMetaObjectProvider 속성에 액세스 할 수 있습니다 (또는 리플렉션을하는 모든 일반 오브젝트) ... 내가 뭔가를 놓치지 않는 한. – jbtule