c# - LINQ select from Collection

Viewed 52053

I'm attempting to write a simple Select method on a class that inherits from 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);
}

Some problems I'm having:

First:

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

OK, where does the CAST go?

Second:

  • Someone could pass in an invalid colName value (i.e. String.IsNullOrEmpty(colName)) or a null parameter (object value == null).

How would I handle the way my function returns if the input parameters are invalid?

[Solved]

I edited my Select statement (even renamed it per the suggestions here). I had to use a switch to cast to the data type that the data was in, but it does work.

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

[Solved (short version)]

Jon Skeet posted this about the same time I posted my solution, and (as always) his code is much nicer.

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

@Jon Skeet: If I ever see your face in the same line at some software developer position I'm applying for, I'm just going to turn around and go home.

@Everyone: Thanks for all the help!

4 Answers
Related