C # DynamicObject: есть ли способ получить доступ к свойствам по индексу? - PullRequest
4 голосов
/ 10 ноября 2011

Есть ли способ доступа к свойствам динамического объекта по индексу?

List<dynamic> list = _dataStagingManager.GetStatusList(consoleSearch);
foreach (var row in list)
{
    Console.WriteLine(row[0]);
    Console.WriteLine(row[1]);
}

В этом примере имя свойства строки [0] отличается в зависимости от результатов псевдонима столбца хранимой процедуры.

Ответы [ 4 ]

4 голосов
/ 10 ноября 2011

К сожалению, нет. В отличие от объектов времени выполнения (которые имеют итеративную коллекцию своих членов, которую можно легко отразить / запросить), динамические объекты по умолчанию не имеют такой коллекции. Они могут быть реализованы любым способом, который позволяет их членам быть доступными по имени. Нет представления об индексах с динамическими объектами, если вы не решите их реализовать самостоятельно.

Если вы хотите, вы можете переопределить метод TryGetIndex для вашего динамического типа, чтобы обеспечить поддержку индексирования.

2 голосов
/ 10 ноября 2011

В общем, это невозможно. Например, вы можете создать динамический объект, который имеет все возможные свойства:

class AnythingGoes : DynamicObject
{
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = binder.Name;
        return true;
    }
}

Есть вероятность, что вы сможете получить список свойств. Если динамический объект на самом деле является нормальным объектом (который не реализует IDynamicMetaObjectProvider), нормальное отражение будет работать нормально.

Если объект на самом деле является динамическим (реализует IDynamicMetaObjectProvider), вы можете попробовать вызвать GetDynamicMemberNames() для DynamicMetaObject, возвращенного из GetMetaObject(). Но, как показывает пример выше, это не гарантированно работает.

0 голосов
/ 10 ноября 2011

Я не знаком с Dapper Dot Net , но после короткого взгляда на него выглядит так, как будто он возвращает анонимные типы в виде динамических объектов. Вы можете рассматривать их как POCO (простые старые объекты CLR), что означает, что они являются классами с индивидуальными именованными свойствами, возможно, не реализуют какой-либо индексатор, который вам необходим для доступа к полям по индексу.

Вы можете попробовать использовать Reflection для достижения чего-то похожего:

foreach (dynamic propInfo in row.GetType().GetProperties())
{
    Console.WriteLine("{0}: {1}", propInfo.Name, propInfo.GetValue(row, null));
}

Я не уверен, что вы получите свойства в том же порядке, в котором их возвращает хранимая процедура.

0 голосов
/ 10 ноября 2011

Если тип времени выполнения row имеет целочисленный индексатор, то ваш код должен быть в порядке как есть.

...