Возrotation анонимного типа в C #

У меня есть запрос, который возвращает анонимный тип, а запрос – в методе. Как вы пишете это:

public "TheAnonymousType" TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new { SomeVariable = ...., AnotherVariable = ....} ).ToList(); return "TheAnonymousType"; } } 

Вы не можете.

Вы можете возвращать только object или контейнер объектов, например IEnumerable , IList и т. Д.

Вы можете вернуть dynamic который даст вам проверенную версию анонимного типа, но только в .NET 4+

Вы не можете возвращать анонимные типы. Можете ли вы создать модель, которая может быть возвращена? В противном случае вы должны использовать object .

Вот статья, написанная Джоном Скитом по этому вопросу

Код из статьи:

 using System; static class GrottyHacks { internal static T Cast(object target, T example) { return (T) target; } } class CheesecakeFactory { static object CreateCheesecake() { return new { Fruit="Strawberry", Topping="Chocolate" }; } static void Main() { object weaklyTyped = CreateCheesecake(); var stronglyTyped = GrottyHacks.Cast(weaklyTyped, new { Fruit="", Topping="" }); Console.WriteLine("Cheesecake: {0} ({1})", stronglyTyped.Fruit, stronglyTyped.Topping); } } 

Или, вот еще одна подобная статья

Или, как комментируют другие, вы можете использовать dynamic

Вы можете использовать class Tuple в качестве замены анонимных типов при необходимости возврата:

Примечание. Кортеж может содержать до 8 параметров.

 return Tuple.Create(variable1, variable2); 

Или, например, из исходного сообщения:

 public List> TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select Tuple.Create(..., ...) ).ToList(); return TheQueryFromDB.ToList(); } } 

http://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx

Компилятор C # является двухфазным компилятором. На первом этапе он просто проверяет пространства имен, иерархии classов, сигнатуры методов и т. Д. Органы метода компилируются только во время второй фазы.

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

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

Именно по этой причине анонимные типы не могут использоваться в качестве типа возврата.

Как и другие, если вы используете .net 4.0 или grater, вы можете использовать Dynamic .

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

Три варианта:

Опция 1:

 public class TheRepresentativeType { public ... SomeVariable {get;set;} public ... AnotherVariable {get;set;} } public IEnumerable TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new TheRepresentativeType{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB; } } 

Вариант 2:

 public IEnumerable TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new TheRepresentativeType{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB; } } 

вы можете повторить его как объект

Вариант 3:

 public IEnumerable TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new TheRepresentativeType{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB; //You may need to call .Cast(), but I'm not sure } } 

и вы сможете перебирать его как динамический объект и напрямую обращаться к их свойствам

В C # 7 мы можем использовать кортежи для этого:

 public List<(int SomeVariable, string AnotherVariable)> TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new { SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB.Select(s => (SomeVariable = s.SomeVariable, AnotherVariable = s.AnotherVariable)).ToList(); } } 

Возможно, вам придется установить пакет System.ValueTuple nuget.

Вы можете вернуть список объектов в этом случае.

 public List TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new { SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB ; } } 
 public List TheMethod(SomeParameter) { using (MyDC TheDC = new MyDC()) { var TheQueryFromDB = (.... select new SomeClass{ SomeVariable = ...., AnotherVariable = ....} ).ToList(); return TheQueryFromDB.ToList(); } } public class SomeClass{ public string SomeVariable{get;set} public string AnotherVariable{get;set;} } 

Создание собственного classа и запросов для него – лучшее решение, которое я знаю. Насколько я знаю, вы не можете использовать значения возвращаемого анонимного типа в другом методе, потому что это будет не просто признано. Однако они могут использоваться в одном и том же метод. Я использовал их как IQueryable или IEnumerable , хотя он все еще не позволяет вам видеть, что находится внутри переменной анонимного типа.

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

Вы можете использовать только динамическое ключевое слово,

  dynamic obj = GetAnonymousType(); Console.WriteLine(obj.Name); Console.WriteLine(obj.LastName); Console.WriteLine(obj.Age); public static dynamic GetAnonymousType() { return new { Name = "John", LastName = "Smith", Age=42}; } 

Но с ключевым словом dynamic вы потеряете безопасность времени компиляции, IDE IntelliSense и т. Д. …

Давайте будем гением компьютера.