Анонимные типы

У меня есть a Dictionary(TKey, TValue) как

Dictionary Deduction_Employees = 
    new Dictionary();

и позже я добавляю к тому списку массива анонимный тип как это

var day_and_type = new {
    TheDay = myDay,
    EntranceOrExit = isEntranceDelay
};

Deduction_Employees[Employee_ID].Add(day_and_type);

Теперь, как я могу распаковать тот var и получить доступ к тем свойствам??

6
задан ICR 20 February 2010 в 14:02
поделиться

5 ответов

Во-первых, вы не раскрываете тип. Анонимные типы - это ссылочные типы, а не структуры.

Даже если вы технически можете создавать экземпляры одного и того же типа вне метода, в котором они были объявлены (согласно разделу 7.5.10.6 спецификации языка C# 3.0, который гласит:

В пределах одной программы два анонимных инициализатора объекта, которые определяют последовательность свойств с одинаковыми имен и типов во время компиляции в одинаковом порядке, создадут экземпляры одного и того же анонимного типа.

) у вас нет возможности получить имя типа, которое вам нужно для того, чтобы выполнить приведение от Object обратно к созданному вами типу. Вам пришлось бы прибегнуть к решению cast-by-example, которое по своей сути несовершенно.

Cast-by-example несовершенен, потому что с точки зрения дизайна, каждый раз, когда вы хотите получить доступ к типу вне объявленной функции (и все еще внутри того же модуля), вы должны фактически объявлять тип заново.

Это дублирование усилий, которое приводит к небрежному проектированию и реализации.

Если вы используете .NET 4.0, то вы можете поместить экземпляр объекта в динамическую переменную. Однако основным недостатком является отсутствие проверки доступа к членам во время компиляции. Вы легко можете неправильно написать имя члена, и тогда вместо ошибки компиляции вы получите ошибку времени выполнения.

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

13
ответ дан 8 December 2019 в 04:08
поделиться

Есть несколько способов.

Поскольку комментарии, похоже, указывают на то, что я предлагаю вам сделать это, позвольте мне уточнить: Вы должны создать именованный тип для вашего объекта, поскольку вы собираетесь передавать его по кругу.

Во-первых, вы можете использовать Reflection, на что уже указывал другой ответ здесь.

Другой способ, который обманет .NET и заставит вас выдать нужный тип, известен как "приведение по примеру", и он выглядит примерно так: Вам нужно передать свой объект через вызов общего метода, который вернет объект нужного типа, сделав вывод о том, какой тип нужно вернуть.

Например, попробуйте это:

private static T CastByExample<T>(T example, object value)
{
    return (T)value;
}

и чтобы использовать это:

var x = CastByExample(new { TheDay = ??, EntranceOrExit = ?? }, obj);

для двух точек ??, вам просто нужно передать что-то подходящее к типу данных для этих свойств, значения не будут использоваться.

Это использует тот факт, что несколько анонимных типов, содержащих точно такие же свойства, одного типа, в одном и том же порядке, в одной и той же сборке, будут отображаться на один единственный тип.

Однако к этому времени вы уже должны создавать именованный тип.

8
ответ дан 8 December 2019 в 04:08
поделиться

Нет, не можете. Вы можете получить доступ к свойствам только с помощью отражения. Компилятор не может узнать, что это за тип, и, поскольку это анонимный тип, вы также не можете его преобразовать.

1
ответ дан 8 December 2019 в 04:08
поделиться

Анонимный тип имеет область действия. Чтобы передать анонимный тип или коллекцию, содержащую анонимные типы, за пределы метода, необходимо сначала привести тип к объекту. Однако это побеждает строгую типизацию анонимного типа. Если вы должны сохранить результаты запроса или передать их за пределы метода, рассмотрите возможность использования обычной именованной структуры или класса вместо анонимного типа.

Источник: http://msdn.microsoft.com/en-us/library/bb397696.aspx

3
ответ дан 8 December 2019 в 04:08
поделиться

Если вы используете .NET 1.x - 3.x, вы должны использовать отражение.

Если вы используете .NET 4.0, вы можете использовать динамический тип и вызывать ожидаемые свойства.

Ни в том, ни в другом случае распаковывать не нужно; это для типов значений. Анонимные типы всегда являются ссылочными типами.

1
ответ дан 8 December 2019 в 04:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: