Анонимные типы - PullRequest
       28

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

6 голосов
/ 20 февраля 2010

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

Dictionary<int, ArrayList> Deduction_Employees = 
    new Dictionary<int, ArrayList>();

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

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

Deduction_Employees[Employee_ID].Add(day_and_type);

Теперь как можноЯ распаковываю этот var и получаю доступ к этим свойствам ??

Ответы [ 5 ]

13 голосов
/ 20 февраля 2010

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

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

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

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

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

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

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

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

8 голосов
/ 20 февраля 2010

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

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

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

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

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

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

и использовать его:

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

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

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

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

3 голосов
/ 20 февраля 2010

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

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

1 голос
/ 20 февраля 2010

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

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

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

1 голос
/ 20 февраля 2010

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

...