List的返回类型

时间:2012-12-24 16:37:23

标签: c# linq anonymous-types

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

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的类型。在这种情况下我该怎么做?

4 个答案:

答案 0 :(得分: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;
编辑:为了澄清我的第一个陈述,正如@JamesMichaelHare指出的那样,技术上可以通过返回objectdynamic从方法返回匿名类型,但它可能比它更麻烦值得,因为您必须使用Reflection或其他方式来访问对象的属性。

答案 1 :(得分:9)

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

所以试试这个:

public IEnumerable<dynamic> ListOfProducts(string subcategory) 

答案 2 :(得分: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; }
}

答案 3 :(得分:1)

注意:匿名类型被设计为在方法(或函数)的范围内使用,而不是在它之外。

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

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

另一件事:匿名类型在程序集内部有效,不能跨程序集边界传递。来自here

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

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