dynamic
문자열 로 c # 속성 값에 액세스하고 싶습니다 .
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
문자열로 “value2″만있는 경우 d.value2 ( “random”) 값을 얻으려면 어떻게해야합니까? 자바 스크립트에서는 d [ “value2”]를 사용하여 값 ( “random”)에 액세스 할 수 있지만 C # 및 리플렉션을 사용하여이 작업을 수행하는 방법을 잘 모르겠습니다. 내가 온 가장 가까운 것은 이것입니다 :
d.GetType().GetProperty("value2")
…하지만 실제 가치를 얻는 방법을 모르겠습니다.
언제나 그렇듯이 도움을 주셔서 감사합니다!
답변
당신은 일단 당신의 PropertyInfo
(에서 GetProperty
), 당신은 전화해야 GetValue
하고의 가치를 얻을하려는 인스턴스에 전달합니다. 귀하의 경우 :
d.GetType().GetProperty("value2").GetValue(d, null);
답변
public static object GetProperty(object target, string name)
{
var site = System.Runtime.CompilerServices.CallSite<Func<System.Runtime.CompilerServices.CallSite, object, object>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, name, target.GetType(), new[]{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0,null)}));
return site.Target(site, target);
}
Microsoft.CSharp에 대한 참조를 추가하십시오. 동적 유형 및 개인 속성 및 필드에도 작동합니다.
편집 :이 방법이 작동하는 동안 Microsoft.VisualBasic.dll 어셈블리 에서 거의 20 배 빠른 방법이 있습니다 .
public static object GetProperty(object target, string name)
{
return Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(target, name, CallType.Get);
}
답변
Dynamitey 는 오픈 소스 .net std
라이브러리이므로 dynamic
키워드 처럼 호출 할 수 있지만 컴파일러가 대신 속성 이름에 문자열을 사용하면 속도가 반향됩니다 (거의 빠르지는 않습니다). 동적 키워드를 사용하는 것과 같지만 이는 컴파일러가 정적으로 캐시하는 동적 캐싱의 추가 오버 헤드 때문입니다.
Dynamic.InvokeGet(d,"value2");
답변
둘 다를 얻기위한 가장 쉬운 방법 setter
과를 getter
포함한 모든 유형의 작동하는 속성 dynamic
및 ExpandoObject
사용하는 것입니다 FastMember
또한 (가 방출을 사용하는) 가장 빠른 방법은 주위를 될 일이.
당신이 중 하나 얻을 수있는 TypeAccessor
특정 유형 또는에 따라 ObjectAccessor
특정 유형의 인스턴스의 기반.
예:
var staticData = new Test { Id = 1, Name = "France" };
var objAccessor = ObjectAccessor.Create(staticData);
objAccessor["Id"].Should().Be(1);
objAccessor["Name"].Should().Be("France");
var anonymous = new { Id = 2, Name = "Hilton" };
objAccessor = ObjectAccessor.Create(anonymous);
objAccessor["Id"].Should().Be(2);
objAccessor["Name"].Should().Be("Hilton");
dynamic expando = new ExpandoObject();
expando.Id = 3;
expando.Name = "Monica";
objAccessor = ObjectAccessor.Create(expando);
objAccessor["Id"].Should().Be(3);
objAccessor["Name"].Should().Be("Monica");
var typeAccessor = TypeAccessor.Create(staticData.GetType());
typeAccessor[staticData, "Id"].Should().Be(1);
typeAccessor[staticData, "Name"].Should().Be("France");
typeAccessor = TypeAccessor.Create(anonymous.GetType());
typeAccessor[anonymous, "Id"].Should().Be(2);
typeAccessor[anonymous, "Name"].Should().Be("Hilton");
typeAccessor = TypeAccessor.Create(expando.GetType());
((int)typeAccessor[expando, "Id"]).Should().Be(3);
((string)typeAccessor[expando, "Name"]).Should().Be("Monica");
답변
동적 객체를 요청할 때 대부분의 경우 ExpandoObject를 얻습니다 (위의 익명이지만 정적으로 유형이 지정된 예제에는 없지만 JavaScript 및 선택한 JSON 파서 JsonFx에 대해서는 ExpandoObjects를 생성합니다).
동적이 실제로 ExpandoObject 인 경우 http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx에 설명 된대로 IDictionary로 캐스팅하여 리플렉션을 피할 수 있습니다 .
IDictionary로 캐스팅하면 .Item 및 .ContainsKey와 같은 유용한 메소드에 액세스 할 수 있습니다.
답변
GetProperty / GetValue는 Json 데이터에서 작동하지 않으며 항상 null 예외를 생성하지만 다음 방법을 시도 할 수 있습니다.
JsonConvert를 사용하여 객체를 직렬화하십시오.
var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));
그런 다음 문자열에 직접 캐스팅하여 액세스하십시오.
var pn = (string)z["DynamicFieldName"];
Convert.ToString (request) [ “DynamicFieldName”]을 적용해도되지만, 테스트하지는 않았습니다.
답변
d.GetType (). GetProperty ( “value2”)
PropertyInfo 객체를 반환합니다.
그럼 해
propertyInfo.GetValue(d)