【问题标题】:Return type for a List列表的返回类型
【发布时间】:2012-12-24 16:37:22
【问题描述】:

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

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,这种情况应该怎么办?

【问题讨论】:

  • 我认为你不能那样做,因为类型是方法的本地类型。声明其他人可以实际使用的公共类型。
  • 你会如何使用这个方法?
  • 我在你的另一个问题中给了你答案——你需要用你想要的属性声明你自己的类。您对我之前的评论有什么不明白的地方?
  • 取决于您将如何使用该方法,您可能会用到类似stackoverflow.com/questions/612689/…
  • Return anonymous type?的可能重复

标签: c# linq anonymous-types


【解决方案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;

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

【讨论】:

  • 我会这样做。
  • 澄清一下,您是正确的,因为您不能将方法的返回类型设为匿名类型,但可以从方法返回匿名对象 (如 objectdynamic 等),但实际上,如果对象的作用域超出了生命周期匿名类型中的方法,那并不是最好的,而自定义类会更好。您说得对,只是想确保他们没有将其视为无法退回匿名对象本身...
【解决方案2】:

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

所以试试这个吧:

public IEnumerable<dynamic> ListOfProducts(string subcategory) 

【讨论】:

    【解决方案3】:

    我要说的是,你应该为此定义另一个模型,如果你将返回结果用于表示层,你应该定义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);
      

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

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

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

      【讨论】:

        猜你喜欢
        • 2012-06-09
        • 2019-08-26
        • 2013-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多