Подтвердить что ты не робот

Тип возврата для списка

Привет, мне нужно найти способ объявить анонимный тип метода. Это мой код:

public List<var> ListOfProducts(string subcategory)
{
    var products = (from p in dataContext.Products
                    join s in dataContext.SubCategories.Where(x => x.SubCatName == subcategory)
                        on p.SubcatId equals s.SubCatId
                    join b in dataContext.Brands on p.BrandId equals b.BrandId
                    select new
                    {
                        Subcategory = s.SubCatName,
                        Brand = b.BrandName,
                        p.ProductName,
                        p.ProductPrice
                    });
    return products;
} 

Я не знаю, какой тип должен установить List для метода. Что делать в этом случае?

4b9b3361

Ответ 1

Вы не можете вернуть Anonymous Type из метода.

Просто создайте класс для своего типа и верните его.

public class Product
{
    string Subcategory { get; set; }
    string Brand { get; set; }
    string ProductName { get; set; }
    decimal ProductPrice { get; set; }
}

Затем верните как таковой:

var products = (from p in dataContext.Products
                    join s in dataContext.SubCategories.Where(x => x.SubCatName == subcategory) on p.SubcatId
                        equals s.SubCatId
                    join b in dataContext.Brands on p.BrandId equals b.BrandId
                    select new Product
                               {
                                   Subcategory = s.SubCatName,
                                   Brand = b.BrandName,
                                   p.ProductName,
                                   p.ProductPrice
                               });

    return products;

EDIT: Чтобы прояснить мой первый оператор, как отмечает @JamesMichaelHare, технически можно вернуть анонимный тип из метода, возвращая object или dynamic, но это, вероятно, больше хлопот, чем это стоит, d необходимо использовать Reflection или какой-либо другой способ доступа к свойствам вашего объекта.

Ответ 2

В соответствии с MSDN динамический тип включает операции, в которых он происходит, для обхода проверки типа компиляции. Вместо этого эти операции разрешаются во время выполнения.

Итак, попробуйте вместо этого:

public IEnumerable<dynamic> ListOfProducts(string subcategory) 

Ответ 3

Что бы я сказал, вы должны определить другую модель для этого, если вы используете возвращаемый результат для уровня Presentation, вы должны определить ViewModel, или если вы используете для уровня распространения, вы можете определить как объект Dto

public class ProductDto
{
    public string Subcategory {get; set; }
    public string Brand { get; set; }
    public string ProductName{ get; set; }
    public decimal ProductPrice{ get; set; }
}

Ответ 4

Просто примечание: анонимные типы предназначены для использования внутри области применения метода (или функции) не вне его.

Но есть способ сделать это с помощью некоторых методов расширения и некоторых дополнительных отливок (мне это не нравится):

(В вашем коде вы также должны добавить .ToList() в выражение LINQ.)

Методы расширения:

static List<T> InitList<T>(this T o) { return new List<T>(); }
static T CastToThis<T>(this  T target, object o) { return (T)o; }

Вы можете инициализировать список анонимного типа:

var list = new { Name = "Name", Age = 40 }.InitList();

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

list = list.CastToThis(returnedValueOfYourMethod);

И еще одно: анонимные типы действительны только внутри сборки и не могут быть переданы через границы сборок. Из здесь:

Спецификация С# гарантирует, что при использовании "одного и того же" анонимного типа в двух местах в одной сборке типы объединяются в один тип. Чтобы быть "тем же", два анонимных типа должны иметь одинаковые имена членов и одинаковые типы членов в том же порядке.

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