Как я могу передать анонимные типы в качестве параметров другим функциям? Рассмотрим этот пример:
var query = from employee in employees select new { Name = employee.Name, Id = employee.Id };
LogEmployees(query);
Переменная query
здесь не имеет строгого типа. Как мне определить мою LogEmployees
функцию, чтобы принять ее?
public void LogEmployees (? list)
{
foreach (? item in list)
{
}
}
Другими словами, что я должен использовать вместо ?
знаков.
c#
function
parameters
anonymous-types
Саид Нямати
источник
источник
Ответы:
Я думаю, что вы должны сделать класс для этого анонимного типа. Это было бы наиболее разумно, по моему мнению. Но если вы действительно не хотите, вы можете использовать динамику:
Обратите внимание, что это не является строго типизированным, поэтому, если, например, имя изменяется на EmployeeName, вы не будете знать, что есть проблема до времени выполнения.
источник
dynamic
использования. Я очень пригодился для меня. Спасибо :)Вы можете сделать это так:
... но вы не сможете сделать многое с каждым предметом. Вы можете вызвать ToString, но вы не сможете использовать (скажем)
Name
иId
напрямую.источник
where T : some type
в конце первой строки, чтобы сузить тип. В этот момент, тем не менее, ожидание определенного типа общего интерфейса имело бы больше смысла ожидать интерфейса. :)where T : some type
с анонимными типами, поскольку они не реализуют какой-либо интерфейс ...К сожалению, то, что вы пытаетесь сделать, невозможно. Под капотом переменная запроса вводится
IEnumerable
как анонимная. Имена анонимных типов не могут быть представлены в пользовательском коде, поэтому невозможно сделать их входным параметром функции.Лучше всего создать тип и использовать его в качестве результата запроса, а затем передать его в функцию. Например,
Однако в этом случае вы выбираете только одно поле, поэтому может быть проще просто выбрать поле напрямую. Это приведет к тому, что запрос будет напечатан как
IEnumerable
тип поля. В этом случае имя столбца.источник
Equals
меняется поведение. Т.е. вы должны это реализовать. (Я знал об этом несоответствии, но все же сумел забыть об этом во время рефакторинга.)Вы не можете передать анонимный тип не универсальной функции, если тип параметра не равен
object
.Анонимные типы предназначены для краткосрочного использования в методе.
Из MSDN - анонимные типы :
(акцент мой)
Обновить
Вы можете использовать дженерики для достижения желаемого:
источник
object
- илиdynamic
; пobject
Согласно моему ответу, использование - это не то же самое, что создание общего метода для анонимного типа.Обычно вы делаете это с помощью дженериков, например:
Затем компилятор должен определить,
T
когда вы вызываетеMapEntToObj(query)
. Не совсем уверен, что вы хотите сделать внутри метода, поэтому я не могу сказать, полезно ли это ... проблема в том, что внутриMapEntToObj
вы все еще не можете назватьT
- вы также можете:T
T
чтобы делать вещино кроме этого, довольно трудно манипулировать анонимными типами - не в последнюю очередь потому, что они неизменны ;-p
Еще одна хитрость (при извлечении данных) - также передать селектор, то есть что-то вроде:
источник
Вы можете использовать дженерики со следующим приемом (приведение к анонимному типу):
источник
«Динамический» также может быть использован для этой цели.
источник
Вместо передачи анонимного типа передайте список динамического типа:
var dynamicResult = anonymousQueryResult.ToList<dynamic>();
DoSomething(List<dynamic> _dynamicResult)
DoSomething(dynamicResult);
Спасибо Петру Иванову !
источник
Если вы знаете, что ваши результаты реализуют определенный интерфейс, вы можете использовать интерфейс как тип данных:
источник
Я бы использовал
IEnumerable<object>
как тип для аргумента. Тем не менее, это не большой выигрыш для неизбежного явного приведения. ураисточник