Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 30.05.2014
Сообщений: 32

Получить доступ до членов анонимного типа

13.05.2015, 23:25. Показов 3890. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
путаюсь в анонимных типах.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var a1 = new { A = 123, B = "text string" };
Console.WriteLine("a1 = {0}", a1);
// здесь все понятно
Console.WriteLine("a1.A = {0}", a1.A);
Console.WriteLine("a1.B = {0}", a1.B);
 
Func<object> fa2 = () => { return new { A = 234, B = "new string" }; };
var a2 = fa2();
Console.WriteLine("a2 = {0}", a2);
// а здесь при попытке обращения к члену анонимного типа получаю ошибку
Console.WriteLine("a2 = {0}", a2.A);    // error CS1061: 'object' does not contain a definition for 'A'
                        // and no extension method 'A' accepting a first argument
                        // of type 'object' could be found (are you missing
                        // a using directive or an assembly reference?)
наверняка проблема в том, что Func<object> fa2 возвращает тип object, и его нужно к чему-то привести, чтобы компилятор разобрался что к чему.

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

Code
1
2
3
4
a1 = { A = 123, B = text string }
a1.A = 123
a1.B = text string
a2 = { A = 234, B = new string }
значит, возможность добраться до членов типа есть. но какая?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.05.2015, 23:25
Ответы с готовыми решениями:

Изменение переменной анонимного типа
Есть список dynamic мне надо изменить одно из полей class Program { static List&lt;dynamic&gt; list = new...

Linq Aggregate для анонимного типа
Добрый день. Допустим, у меня имеется массив от 1 до 10 и строка, содержащая 0 и 1, равная длине этого массива. Задачей стоит...

Как получить доступ к методам из переменной типа Object
Задача вот какая. Пишу DLL для стороннего софта и нужна функция которая получает некоторый класс(спецификации и реализации которого у меня...

15
 Аватар для Metall_Version
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
13.05.2015, 23:35
ни как, тут нужно использовать класс.
1
0 / 0 / 0
Регистрация: 30.05.2014
Сообщений: 32
13.05.2015, 23:38  [ТС]
печаль..
0
 Аватар для diadiavova
7259 / 2606 / 744
Регистрация: 11.04.2015
Сообщений: 4,150
Записей в блоге: 43
13.05.2015, 23:46
blackofe, в восьмой строке замени var на dynamic
C#
1
dynamic a2 = fa2();
1
 Аватар для Metall_Version
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
14.05.2015, 00:00
Цитата Сообщение от diadiavova Посмотреть сообщение
в восьмой строке замени var на dynamic
как вариант, но если используется анонимный тип то он используется в пределе одного метода, и таких проблем как в топике не возникает, если возникает то используют классы.

а чисто ради интереса/чтобы заработало можно динамик заюзать.
0
 Аватар для diadiavova
7259 / 2606 / 744
Регистрация: 11.04.2015
Сообщений: 4,150
Записей в блоге: 43
14.05.2015, 00:15
Metall_Version, на самом деле это все шарповские заморочки. В VB.Net этой проблемы вообще нет. Поскольку при инициализации переменной лямбда-выражением там вполне корректно выводится сигнатура, при точно такой же ситуации есть возможность обращаться к членам типа и даже подсказки по ним получать.
Миниатюры
Получить доступ до членов анонимного типа  
1
0 / 0 / 0
Регистрация: 30.05.2014
Сообщений: 32
14.05.2015, 16:58  [ТС]
dynamic работает. конечно, intellisense ничего не показывает (и не должен), но вывод члена компилируется и значение выводится.

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

diadiavova,
а вот это совсем непонятно. неужели у vb.net такие отличия от c#?!

кстати, вышеуказанный тест из vs 2013. проверил в 2015 - та же история.
0
 Аватар для diadiavova
7259 / 2606 / 744
Регистрация: 11.04.2015
Сообщений: 4,150
Записей в блоге: 43
14.05.2015, 17:00
blackofe, все имеет свою цену. Хотя беспокоиться о производительности всего приложения явно не стоит. Оптимизация производительности на ранних этапах разработки чаще всего оборачивается "экономией на спичках". Не стоит отказываться от удобств ради того, что, возможно, в конечном итоге и значения-то иметь не будет.
Что до ошибок времени исполнения в результате использования позднего связывания, ну тут опасность есть и в принципе каждый уже сам для себя решает, стоит оно того или нет в каждой конкретной ситуации. Злоупотреблять этим я бы не стал, но знать о том, что данную проблему можно решить, ну по крайней мере, если "кровь с носа" надо - совсем не лишне, ИМХО.

Добавлено через 2 минуты
Цитата Сообщение от blackofe Посмотреть сообщение
неужели у vb.net такие отличия от c#?!
Там намного больше отличий, чем это принято думать. Мало того, в последних версиях шарп существенно наверстал отставание, раньше было все гораздо хуже. Бейсик намного гибче.
0
0 / 0 / 0
Регистрация: 30.05.2014
Сообщений: 32
14.05.2015, 17:08  [ТС]
я подумал, что, наверное проблема в том, что мне приходится сочинять функтор, возвращающий тип "объект"

Code
1
Func<object>
конечно, компилятор не может сообразить, что в объекте на самом деле находится анонимный тип с определенной структурой.

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

Добавлено через 3 минуты

Не по теме:

Цитата Сообщение от diadiavova Посмотреть сообщение
Там намного больше отличий, чем это принято думать. Мало того, в последних версиях шарп существенно наверстал отставание, раньше было все гораздо хуже. Бейсик намного гибче.
я бейском баловался "на заре советской власти". мой основной язык - c++. тестовые утилиты под виндами я рисовал на бейсике, пока не пришел шарп, на который я с радостью пересел - ибо синтаксически он мне ближéе.

0
 Аватар для diadiavova
7259 / 2606 / 744
Регистрация: 11.04.2015
Сообщений: 4,150
Записей в блоге: 43
14.05.2015, 17:10
blackofe, тут проблема как раз-таки в том и есть, что джинерик-параметру надо передать уже описанный тип. Учитывая, что шарп не умеет из лямбда-выражения выводить тип делегата, решения проблемы видимо нет.
Цитата Сообщение от blackofe Посмотреть сообщение
я бейском баловался "на заре советской власти". мой основной язык - c++. тестовые утилиты под виндами я рисовал на бейсике, пока не пришел шарп, на который я с радостью пересел - ибо синтаксически он мне ближéе.
Я говорю именно о VB.Net, который появился одновременно с шарпом. Со старым бейсиком у него сходство преимущественно внешнее.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
14.05.2015, 17:36
Лучший ответ Сообщение было отмечено Ev_Hyper как решение

Решение

Цитата Сообщение от blackofe Посмотреть сообщение
но какая?
Например, метод-обертка:
C#
1
2
3
4
Func<T> Create<T>(Func<T> f)
{
    return f;
}
C#
1
2
var fa2 = Create(() => new { A = 234, B = "new string" });
fa2(). // <-- вывалится подсказка IntelliSense
4
0 / 0 / 0
Регистрация: 30.05.2014
Сообщений: 32
14.05.2015, 18:45  [ТС]
kolorotur,
спасибо, работает. но этот способ требует вводить дополнительный метод, а я очень не люблю порождать лишние сущности без особой на то нужды.

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

я люблю пользоваться короткоживущими объектами, типа:

C#
1
string pubkey = new RSACryptoServiceProvider().ToXmlString(false);
но в моем случае я не мог написать так:

C#
1
2
string pubkey = new RSACryptoServiceProvider().ToXmlString(false);
string privkey = new RSACryptoServiceProvider().ToXmlString(true);
потому что ключи получаются от двух разных провайдеров, а они должны друг другу соответствовать.

мне нравится в c++ заворачивать в лямбда-выражения какие-нибудь локальные сиюместные функции. к примеру

C++
1
2
3
4
const string pcbcode([](const Q::QTranAdm &Tr) {
            const string PCB(Tr.Get("PCB"));
            return PCB.empty() ? (string)Tr.Get("Branch") : PCB;
        }(tr));
процесс взятия переменной pcbcode скрыт в лямбда-выражении, который мне больше нигде не понадобится, и поэтому не хочется городить для этого отдельную функцию-член класса.

родилась идея применить подобное в c#:

C#
1
2
3
var keypair = /* лямбда-выражение, которое бы что-то сделало внутри
                и вернуло пару ключей в виде объекта анонимного типа,
                членами которого были бы эти ключи */
однако вызвать лямбду напрямую в c# у меня не получилось. поэтому и родилась немножко корявая конструкция:

C#
1
2
3
4
5
6
7
8
9
10
11
12
Func<object> getkeys = () => {
            var provider = new RSACryptoServiceProvider();
            return new {
                Public = provider.ToXmlString(false),
                Private = provider.ToXmlString(true)
            };
        };
 
var keys = getkeys();
 
Console.WriteLine("keys = {0}", keys);  // ключи выводятся
Console.WriteLine("keys.Public = {0}", keys.Public);    // error CS1061
keys - переменная анонимного типа, содержащая в себе Public и Private, но, по-видимому, из-за боксинга информация о них теряется.

возможно, если бы мне удалось применить c++-подход и нарисовать что-то вроде:

C#
1
2
3
4
5
6
7
8
9
10
var keys = (() => { // error CS0149: Method name expected
            var provider = new RSACryptoServiceProvider();
            return new {
                Public = provider.ToXmlString(false),
                Private = provider.ToXmlString(true)
            };
        })();
 
Console.WriteLine("keys = {0}", keys);  // ключи выводятся
Console.WriteLine("keys.Public = {0}", keys.Public);
но c# такое не компилирует - выдает ошибку CS0149.

я, наверное, еще не достиг того уровня эквилибристики, после которого лямбды просто вылетают из-под пальцев как печеные пирожки. прошу меня за это простить и посоветовать, как все это можно красиво сделать.
0
 Аватар для Metall_Version
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
14.05.2015, 18:46
blackofe, если анонимный тип используется вне метода, то это вполне особая нужда чтобы написать класс. Анонимные нужны только в контексте одного метода
1
0 / 0 / 0
Регистрация: 30.05.2014
Сообщений: 32
14.05.2015, 19:09  [ТС]
Цитата Сообщение от Metall_Version Посмотреть сообщение
blackofe, если анонимный тип используется вне метода, то это вполне особая нужда чтобы написать класс. Анонимные нужны только в контексте одного метода
само собой.

Добавлено через 12 минут

Не по теме:

заголовок моей темы хитрым образом меняется сам без моего участия. ;)

сейчас он выглядит как "Получить доступ до членов анонимного типа", хотя по правилам грамматики логичнее было бы "Получить доступ к членам анонимного типа". но у меня самоотвод - я его таким не сочинял. :)

0
 Аватар для Metall_Version
2152 / 1289 / 516
Регистрация: 04.03.2014
Сообщений: 4,092
14.05.2015, 19:14

Не по теме:

Цитата Сообщение от blackofe Посмотреть сообщение
заголовок моей темы хитрым образом меняется
это не я ..


Цитата Сообщение от blackofe Посмотреть сообщение
логичнее было бы "Получить доступ к членам анонимного типа"
согласен
0
14.05.2015, 19:58  [ТС]

Не по теме:

Цитата Сообщение от Metall_Version Посмотреть сообщение
это не я ..
а я и не говорю. ;)

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.05.2015, 19:58
Помогаю со студенческими работами здесь

Получить доступ к TryParse типа Enum через рефлексию
возникла необходимость восстановить значение перечисления System.Windows.Forms.FormWindowState из строки. Метода Parse или TryParse у этого...

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

Разрешен доступ анонимного пользователя
При сканировании компа антивирусом AVZ пишет что на компе разрешен доступ анонимного пользователя, что это и как запретить доступ?

Anonymous type в linq: Неверное определение члена анонимного типа
здравствуйте! это, практически, мой первый опыт с linq, поэтому не кидайте тапками) такая ситуация: var...

Как получить доступ к элементу массива типа запись
PElem=^TElem; TElem= record {Описание элемента } Marka: string; key:integer; end; PMyArray= array of...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru