Jeśli IDynamicMetaObjectProvider może dostarczyć dynamiczne nazwy członków, możesz je pobrać. Zobacz GetMemberNames wdrożenie w Apache License biblioteki PCL Dynamitey (które można znaleźć w Nuget), to działa na ExpandoObject
S i DynamicObject
S, która wdrożenia GetDynamicMemberNames
i każdy inny IDynamicMetaObjectProvider
, który stanowi przedmiot meta z realizacji GetDynamicMemberNames
bez zwyczaj badania spoza is IDynamicMetaObjectProvider
.
Po uzyskaniu nazw członków potrzeba trochę więcej pracy, aby uzyskać odpowiednią wartość, ale Impromptu to robi, ale trudniej jest wskazać tylko interesujące fragmenty i mieć sens. Oto dokumentacja i jest równa lub szybsza niż odbicie, jednak jest mało prawdopodobne, aby była szybsza niż wyszukiwanie w słowniku dla expando, ale działa dla dowolnego obiektu, expando, dynamicznego lub oryginalnego - nadasz mu nazwę.
W przypadku ExpandoObject klasa ExpandoObject faktycznie implementuje
IDictionary<string, object>
swoje właściwości, więc rozwiązanie jest tak banalne jak rzutowanie:IDictionary<string, object> propertyValues = (IDictionary<string, object>)s;
Zauważ, że to nie zadziała dla ogólnych obiektów dynamicznych. W takich przypadkach musisz przejść do DLR za pośrednictwem IDynamicMetaObjectProvider.
źródło
Należy wziąć pod uwagę kilka scenariuszy. Przede wszystkim musisz sprawdzić typ swojego obiektu. W tym celu możesz po prostu wywołać GetType (). Jeśli typ nie implementuje IDynamicMetaObjectProvider, możesz użyć odbicia takiego samego, jak w przypadku każdego innego obiektu. Coś jak:
var propertyInfo = test.GetType().GetProperties();
Jednak w przypadku implementacji IDynamicMetaObjectProvider prosta refleksja nie działa. Zasadniczo musisz wiedzieć więcej o tym obiekcie. Jeśli jest to ExpandoObject (który jest jedną z implementacji IDynamicMetaObjectProvider), możesz skorzystać z odpowiedzi udzielonej przez itowlson. ExpandoObject przechowuje swoje właściwości w słowniku i możesz po prostu przesłać swój obiekt dynamiczny do słownika.
Jeśli jest to DynamicObject (inna implementacja IDynamicMetaObjectProvider), musisz użyć wszelkich metod, które ujawnia ten DynamicObject. DynamicObject nie musi faktycznie „przechowywać” swojej listy właściwości w dowolnym miejscu. Na przykład może zrobić coś takiego (ponownie używam przykładu z mojego posta na blogu ):
public class SampleObject : DynamicObject { public override bool TryGetMember(GetMemberBinder binder, out object result) { result = binder.Name; return true; } }
W tym przypadku, za każdym razem, gdy spróbujesz uzyskać dostęp do właściwości (o dowolnej nazwie), obiekt po prostu zwraca nazwę właściwości jako ciąg.
dynamic obj = new SampleObject(); Console.WriteLine(obj.SampleProperty); //Prints "SampleProperty".
Nie masz więc nad czym się zastanawiać - ten obiekt nie ma żadnych właściwości, a jednocześnie wszystkie prawidłowe nazwy właściwości będą działać.
Powiedziałbym, że w przypadku implementacji IDynamicMetaObjectProvider musisz przefiltrować znane implementacje, w których możesz uzyskać listę właściwości, takich jak ExpandoObject, i zignorować (lub wyrzucić wyjątek) dla reszty.
źródło
Wymaga Newtonsoft Json.Net
Trochę późno, ale wpadłem na to. Daje ci tylko klucze, a następnie możesz użyć tych na dynamice:
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; }
Wtedy po prostu zawsze tak:
foreach(string propertyName in GetPropertyKeysForDynamic(dynamicToGetPropertiesFor)) { dynamic/object/string propertyValue = dynamicToGetPropertiesFor[propertyName]; // And dynamicToGetPropertiesFor[propertyName] = "Your Value"; // Or an object value }
Decydując się na pobranie wartości w postaci ciągu znaków lub innego obiektu lub wykonanie innej dynamiki i ponowne użycie wyszukiwania.
źródło
JObject attributesAsJObject = dynamicToGetPropertiesFor;
coś jak:var jObject = (JObject) JToken.FromObject(dynamicToGetPropertiesFor);
. W tym momencie możesz uzyskać słownik nazw właściwości i wartości, wykonując coś podobnegovar objProperties = jObject.ToObject<Dictionary<string, object>>();
. Mając to na uwadze, ruszasz na wyścigi. To nie wymaga dynamiki. Działa dobrze ze wszystkim, co jest podklasąDynamicObject