C# 如何调用IEnumerable函数

C# 如何调用IEnumerable函数,c#,ienumerable,C#,Ienumerable,我有这种功能。现在我不知道如何调用它来从字段中获取数据 public static IEnumerable GetMaterialSearch(int reqNo) { DataClassesCRMDataContext dbContext = new DataClassesCRMDataContext(); try { var res = from tbl1 in dbContext.MaterialApplica

我有这种功能。现在我不知道如何调用它来从字段中获取数据

public static IEnumerable GetMaterialSearch(int reqNo)
    {
        DataClassesCRMDataContext dbContext = new DataClassesCRMDataContext();
        try
        {
            var res = from tbl1 in dbContext.MaterialApplicants
                      join tbl2 in dbContext.MaterialRequests on tbl1.ApplicantID equals tbl2.Applicant
                      where tbl2.RCD_ID == reqNo
                      select new
                      {
                          Crusher = tbl2.Crusher,
                          ApplicantID = tbl2.Applicant,
                          Comments = tbl2.Comments,
                          ReqDate = tbl2.ReqDate,
                          Operator = tbl2.Operator,
                          Title = tbl1.Title,
                          Applicant = tbl1.Applicant,
                          Address = tbl1.Address,
                          Nationality = tbl1.Nationality,
                          HouseNo = tbl1.HouseNo,
                          MobileNo = tbl1.MobileNo,
                      };

            if (res.Count() > 0)
            {
                return res.ToList();  
            }
            return null;
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
            return null;
        }
        finally
        {
            dbContext.Connection.Close();
        }
    }
IEnumerable是一个通常用于迭代的序列:

var result = GetMaterialSearch(42);
if (result != null)
    foreach (var entry in result)
        DoSomething(entry);
编辑:如上所述,代码的问题是在IEnumerable结果中返回匿名类型。匿名类型不打算跨越方法边界。发件人:

不能将字段、属性、事件或方法的返回类型声明为具有匿名类型。[…]要将匿名类型或包含匿名类型的集合作为参数传递给方法,可以将参数声明为type object。然而,这样做违背了强类型的目的。如果必须存储查询结果或将它们传递到方法边界之外,请考虑使用普通的命名结构或类,而不是匿名类型。

如果您绝对不想创建命名类,可以使用反射来访问字段,例如通过C4中引入的dynamic关键字:

var result = GetMaterialSearch(42);
if (result != null)
    foreach (dynamic entry in result)
        Console.WriteLine(entry.ID);

您的方法返回非泛型IEnumerable,这就是问题所在。您应该将其更改为泛型IEnumerable,但需要创建另一个类:

class MaterialItem
{
    public string Crusher { get; set; }
    public int ApplicantID { get; set; }
    // (...)
}
然后更改您的方法签名:

public static IEnumerable<MaterialItem> GetMaterialSearch(int reqNo)
但这不是我唯一要做的改变。调用Count以稍后调用ToList会导致不必要的数据库调用

我同意:

var results = res.ToList();
if(results.Any())
    return results;
return null;

你有什么问题?如果res.Count>0{return res.ToList;错误,将导致查询执行两次。执行var res2=res.ToList;return res2.Count>0?res2:null;您应该删除res.Count>0检查,因为它完全没有必要,只会对数据库进行额外调用。有人编写了垃圾代码。应该选择一个具体类型,而不是匿名类型类型。您的方法返回非泛型IEnumerable否。他的问题是他返回的是匿名对象。您甚至表明他不应该返回。您可以枚举IEnumerable非泛型。在.NET 1.0-1.1中,他们只有它,但仍然与集合共存。@xanatos您可以枚举它,但不能以任何其他方式进入它的属性当使用动态或反射时。所以我的语句是有效的。你混淆了林中的树。你说你的方法返回非泛型IEnumerable`这就是问题所在',但你承认这不是问题所在。即使是IEnumerable也很难枚举。问题出在匿名对象中。+1:这是正确的答案除了xanatos在前导句中指出的不精确性之外。只要GetMaterialSearch返回IEnumerable,foreach循环将返回object,因此除非使用动态或反射,否则您将无法获取数据。@MarcinJuraszek:正确;我编辑了我的帖子来解释这一点。@MarcinJuraszek这是错误的。有一些技巧可以解决此问题强制转换为一个匿名类型,然后通过使用var使用它,但它们是丑陋的。@例如,MarcinJuraszek看到。它基于这样一个事实,即在同一个程序集中,具有相同类型的相同参数、顺序相同的所有匿名类型实际上都是一个匿名类型,因此如果在两个位置重新创建它们,则只有一个匿名类型键入。啊……显然我和道格拉斯的想法是一样的:-但这是可能的。不可能和可能之间的区别,但几乎毫无用处:-@MarcinJuraszek啊……我没有从道格拉斯链接的文章中复制代码:-我真的在5分钟内编写了相同的代码和静态代码,参数相同:-:-
var results = res.ToList();
if(results.Any())
    return results;
return null;