c# - LINQ从Collection中选择

jp2*_*ode 9 c# linq visual-studio-2010

我试图Select在继承自的类上编写一个简单的方法IList.

public class RowDataCollection : IList<RowData> {
  private List<RowData> rowList;

  internal RowDataCollection(List<RowData> data) {
    rowList = data;
  }
  // ...
}

public RowDataCollection Rows;

public RowDataCollection Select(string colName, object value) {
  List<RowData> rowList = from item in Rows
         where item[colName].Value == value
         select item;
  return new RowDataCollection(rowList);
}
Run Code Online (Sandbox Code Playgroud)

我遇到的一些问题:

第一:

  • VS2010报道 Cannot implicitly convert type 'IEnumerable<RowData>' to 'List<RowData>'. An explicit conversion exists (are you missing a cast?)

好的,CAST在哪里?

第二:

  • 有人可以传入无效colName值(即String.IsNullOrEmpty(colName))或null参数(object value == null).

如果输入参数无效,我将如何处理函数返回的方式?

[解决了]

我编辑了我的Select陈述(甚至根据这里的建议重新命名).我不得不使用一个开关来转换为数据所在的数据类型,但它确实有效.

public RowDataCollection SelectRow(string colName, object value) {
  if (!String.IsNullOrEmpty(colName) && (value != null) && (0 < Rows.Count)) {
    switch (Rows[0][colName].GetValueType()) {
      case TableDataType.Boolean:
        return new RowDataCollection(Rows.Where(r => (bool)r[colName].Value == (bool)value).ToList());
      case TableDataType.Character:
        return new RowDataCollection(Rows.Where(r => (char)r[colName].Value == (char)value).ToList());
      case TableDataType.DateTime:
        return new RowDataCollection(Rows.Where(r => (DateTime)r[colName].Value == (DateTime)value).ToList());
      case TableDataType.Decimal:
        return new RowDataCollection(Rows.Where(r => (Decimal)r[colName].Value == (Decimal)value).ToList());
      case TableDataType.Integer:
        return new RowDataCollection(Rows.Where(r => (int)r[colName].Value == (int)value).ToList());
      case TableDataType.String:
        return new RowDataCollection(Rows.Where(r => r[colName].Value.ToString() == value.ToString()).ToList());
    }
  }
  return null;
}
Run Code Online (Sandbox Code Playgroud)

[解决(短版)]

Jon Skeet在我发布我的解决方案的同时发布了这个,并且(一如既往)他的代码更好.

public RowDataCollection SelectRow(string colName, object value) {
  List<RowData> rowList = Rows.Where(r => r[colName].Value.Equals(value)).ToList();
  return new RowDataCollection(rowList);
}
Run Code Online (Sandbox Code Playgroud)

@Jon Skeet:如果我在某个软件开发人员的位置看到你的脸在同一行,我正在申请,我只是转身回家.

@Everyone:感谢您的帮助!

Jon*_*eet 11

这样的查询结果不是a List<T>,它是一个IEnumerable<T>.如果你想将其转换为a List<T>,只需调用ToList:

List<RowData> rowList = (from item in Rows
                         where item[colName].Value == value
                         select item).ToList();
Run Code Online (Sandbox Code Playgroud)

碰巧的是,您只是Where在查询中调用.我会把它重写为:

List<RowData> rowList = Rows.Where(item => item[colName].Value.Equals(value))
                            .ToList();
Run Code Online (Sandbox Code Playgroud)

我还将该方法重命名为明显过滤而非投影的方法,因为后者是LINQ中术语"select"的更常见用法.

至于输入参数 - 我建议您验证参数并在它们无效时抛出异常:

if (string.IsNullOrEmpty(colName))
{
    throw new ArgumentException("colName");
}
Run Code Online (Sandbox Code Playgroud)