10

嗨,我需要找到一种方法来为方法声明匿名类型。这是我的代码:

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;
} 

我不知道我应该为方法设置什么类型的列表。在这种情况下我该怎么办?

4

4 回答 4

21

你不能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;

object编辑:为了澄清我的第一个陈述,正如@JamesMichaelHare 指出的那样,从技术上讲,可以通过返回or从方法返回匿名类型dynamic,但这可能比它的价值更麻烦,因为你必须使用Reflection或其他方式访问对象的属性。

于 2012-12-24T16:39:02.157 回答
9

根据 MSDN,动态类型允许其发生的操作绕过编译时类型检查。相反,这些操作是在运行时解决的。

所以试试这个:

public IEnumerable<dynamic> ListOfProducts(string subcategory) 
于 2012-12-24T16:40:21.040 回答
4

我要说的是,您应该为此定义另一个模型,如果您将返回的结果用于表示层,您应该定义 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; }
}
于 2012-12-24T16:42:37.230 回答
2

请注意:匿名类型旨在用于方法(或函数)的范围内,而不是在它之外。

但是有一种方法可以通过一些扩展方法和一些额外的铸件来做到这一点(我不喜欢这样):

(在您的代码中,您也应该将 .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);

还有一件事:匿名类型仅在程序集中有效,不能跨程序集边界传递。从这里

C# 规范向您保证,当您在一个程序集中的两个位置使用“相同”匿名类型时,这些类型会统一为一种类型。为了“相同”,两个匿名类型必须以完全相同的顺序具有完全相同的成员名称和完全相同的成员类型。

总而言之,我不明白你为什么需要这样做,因为声明一个新类型要实用得多,如果你真的需要这个,你应该研究 C# 中的动态类型,如果你要做一些更神奇的事情,你应该使用反射。

于 2012-12-24T18:42:25.797 回答