[C#] 문자열을 통해 C # 동적 속성 값 가져 오기

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포함한 모든 유형의 작동하는 속성 dynamicExpandoObject사용하는 것입니다 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)