Свойства цикла DynamicObject
Я пытаюсь понять тип DynamicObject. Обнаружил, что эта статья MSDN очень краткая и понятная, как создавать и использовать DynamicObject:
http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx
Статья содержит простой класс DynamicDictionary, который наследуется от DynamicObject.
Теперь я хочу перебрать мои динамически созданные свойства DynamicObject:
dynamic d = new DynamicDictionary();
d.Name = "Myname";
d.Number = 1080;
foreach (var prop in d.GetType().GetProperties())
{
Console.Write prop.Key;
Console.Write prop.Value;
}
Очевидно, что это не работает. Я хочу научиться делать это без изменений в моем классе DynamicDictionary, поскольку я действительно пытаюсь научиться использовать это для всех видов существующих объектов, которые наследуются от DynamicObject.
Нужно ли отражение? Я должен что-то упустить...
2 ответа
Вы пробовали метод DynamicDictionary.GetDynamicMemberNames()? - http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.getdynamicmembernames.aspx
Я полагаю, что вы будете заинтересованы в ExpandoObject
учебный класс. DynamicObject
класс - это просто база, где вы должны предоставить всю логику. Он явно реализует IDictionary<string, object>
интерфейс, чтобы вы могли получить доступ к его свойствам или добавить новые таким образом.
// declare the ExpandoObject
dynamic expObj = new ExpandoObject();
expObj.Name = "MyName";
expObj.Number = 1000;
// print the dynamically added properties
foreach (KeyValuePair<string, object> kvp in expObj) // enumerating over it exposes the Properties and Values as a KeyValuePair
Console.WriteLine("{0} = {1}", kvp.Key, kvp.Value);
// cast to an IDictionary<string, object>
IDictionary<string, object> expDict = expObj;
// add a new property via the dictionary reference
expDict["Foo"] = "Bar";
// verify it's been added on the original dynamic reference
Console.WriteLine(expObj.Foo);
Я только что понял, что вы реализуете DynamicDictionary
класс и неправильно понял ваш вопрос. Сожалею.
При использовании с динамической ссылкой у вас есть доступ только к открытым членам. Так как только Count
объявлен публичным (помимо других DynamicObject
члены), вам нужно использовать отражение, чтобы получить доступ к внутреннему словарю, чтобы легко получить эти значения (если вы не собираетесь вносить какие-либо дальнейшие изменения).
Я знаю, что эта тема довольно старая, но для тех, кто все еще задается вопросом, как это сделать, почему бы не использовать TryGetMember()
метод, но создать класс, наследующий GetMemberBinder
, подобно:
public class MyGetMemberBinder : GetMemberBinder
{
public MyGetMemberBinder(string name, bool ignorecase) : base(name, ignorecase) { }
public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)=>throw new NotImplementedException();
}
Затем с LINQ:
Dictionary<string, object> AsStandardDictionary = DynamicDictionary.GetDynamicMemberNames().ToDictionary(x => x, y =>
{
if(DynamicDictionary.TryGetMember(new MyGetMemberBinder(y, false), out var result))
return result;
else
return null;
});