.NET 4의 dynamic 키워드로 선언 된 객체에서 속성 사전과 값을 가져와야합니까? 이것은 반사를 사용하여 작동하지 않는 것 같습니다.
예:
dynamic s = new ExpandoObject();
s.Path = "/Home";
s.Name = "Home";
// How do I enumerate the Path and Name properties and get their values?
IDictionary<string, object> propertyValues = ???
답변
IDynamicMetaObjectProvider가 동적 멤버 이름을 제공 할 수있는 경우이를 가져올 수 있습니다. 참조 은 getMemberNames의 아파치에서 구현 PCL 라이브러리 라이센스 Dynamitey을 (nuget에서 찾을 수있는), 그것은 작동 ExpandoObject
들과 DynamicObject
그 구현이야 GetDynamicMemberNames
및 기타 IDynamicMetaObjectProvider
의 구현과 메타 오브젝트를 제공하는 사람 GetDynamicMemberNames
정의가 이상을 테스트하지 않고 is IDynamicMetaObjectProvider
.
멤버 이름을 얻은 후에는 올바른 방법으로 값을 얻는 것이 약간 더 효과적이지만 Impromptu는이 작업을 수행하지만 흥미로운 부분을 지적하고 이해하기가 더 어렵습니다. 여기 문서가 있으며 리플렉션보다 빠르거나 빠르지 만 expando의 사전 조회보다 빠를 것 같지는 않지만 모든 객체, expando, dynamic 또는 original에서 작동합니다.
답변
ExpandoObject의 경우 ExpandoObject 클래스는 실제로 IDictionary<string, object>
해당 속성을 구현 하므로 솔루션은 캐스팅만큼 간단합니다.
IDictionary<string, object> propertyValues = (IDictionary<string, object>)s;
일반 동적 객체에는 작동하지 않습니다. 이 경우 IDynamicMetaObjectProvider를 통해 DLR로 드롭 다운해야합니다.
답변
고려해야 할 몇 가지 시나리오가 있습니다. 우선, 객체의 유형을 확인해야합니다. 이를 위해 간단히 GetType ()을 호출 할 수 있습니다. 유형이 IDynamicMetaObjectProvider를 구현하지 않으면 다른 객체와 동일한 리플렉션을 사용할 수 있습니다. 다음과 같은 것 :
var propertyInfo = test.GetType().GetProperties();
그러나 IDynamicMetaObjectProvider 구현의 경우 단순 리플렉션이 작동하지 않습니다. 기본적으로이 객체에 대해 더 알아야합니다. 그것이 ExpandoObject (IDynamicMetaObjectProvider 구현 중 하나) 인 경우 itowlson이 제공 한 답변을 사용할 수 있습니다. ExpandoObject는 속성을 사전에 저장하고 동적 객체를 사전에 캐스트 할 수 있습니다.
DynamicObject (다른 IDynamicMetaObjectProvider 구현) 인 경우이 DynamicObject가 노출하는 모든 방법을 사용해야합니다. DynamicObject는 실제로 속성 목록을 어디에나 “저장”할 필요가 없습니다. 예를 들어 다음과 같은 작업을 수행 할 수 있습니다 ( 블로그 게시물 의 예를 재사용하고 있음 ).
public class SampleObject : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = binder.Name;
return true;
}
}
이 경우 지정된 이름으로 속성에 액세스하려고 할 때마다 개체는 속성 이름을 문자열로 반환합니다.
dynamic obj = new SampleObject();
Console.WriteLine(obj.SampleProperty);
//Prints "SampleProperty".
따라서 반영 할 항목이 없습니다.이 개체에는 속성이 없으며 동시에 모든 유효한 속성 이름이 작동합니다.
IDynamicMetaObjectProvider 구현의 경우 ExpandoObject와 같은 속성 목록을 가져오고 나머지 부분은 무시하거나 예외를 throw 할 수있는 알려진 구현을 필터링해야합니다.
답변
Newtonsoft Json.Net 필요
조금 늦었지만 나는 이것을 생각해 냈습니다. 그것은 단지 당신에게 키를 제공하고 당신은 역동적 인 것들을 사용할 수 있습니다 :
public List<string> GetPropertyKeysForDynamic(dynamic dynamicToGetPropertiesFor)
{
JObject attributesAsJObject = dynamicToGetPropertiesFor;
Dictionary<string, object> values = attributesAsJObject.ToObject<Dictionary<string, object>>();
List<string> toReturn = new List<string>();
foreach (string key in values.Keys)
{
toReturn.Add(key);
}
return toReturn;
}
그런 다음 간단히 다음과 같이 가르칩니다.
foreach(string propertyName in GetPropertyKeysForDynamic(dynamicToGetPropertiesFor))
{
dynamic/object/string propertyValue = dynamicToGetPropertiesFor[propertyName];
// And
dynamicToGetPropertiesFor[propertyName] = "Your Value"; // Or an object value
}
값을 문자열 또는 다른 객체로 가져 오거나 다른 동적 작업을 수행하고 조회를 다시 사용하도록 선택합니다.
답변
