I have the following classes:
public class Column
{
public String Name;
public String Value;
}
public class ColumnList : List<Column> {}
Then I do:
var cols = (from c in othercolumnlist
select new Column
{
Name = c.Name,
}).ToList() as ColumnList;
However it returns null. How can I successfully cast into my list?
ColumnList
is a List<Column>
but List<Column>
is not a ColumnList
. Consider Animal
and Dog
classes:
public class Animal
{
}
public class Dog: Animal
{
}
What you are trying to do is treat any animal as dog. But not all animals are dogs. There can be Cat
or Kangaroo
. Thats why as ColumnList
returns null
.
You need to create new ColumnList
instance instead and add columns to it manually:
var columnList = new ColumnList();
columnList.AddRange(othercolumnlist.Select(c => new Column { Name = c.Name }));
If you need to do this often, then you can add static creation method to your ColumnList
class:
public static ColumnList CreateFrom(ColumnList other)
{
var columnList = new ColumnList();
columnList.AddRange(other.Select(c => new Column { Name = c.Name }));
return columnList;
}
And use it this way:
var columnList = ColumnList.CreateFrom(otherColumnList);
What you're trying to do is equivalent to this:
Animal animal = new Animal();
Dog dog = animal as Dog;
One possible solution is to provide a constructor that takes an existing list, and calls the base constructor, such as:
public class ColumnList : List<Column>
{
public ColumnList(IEnumerable<Column> collection):
base(collection)
{
}
}
And then build your ColumnList
from an existing collection.
var collection = othercolumnlist.Select(c => new Column { Name = c.Name });
var columnList = new ColumnList(collection);
You could also provide an extension method to make this easier:
public static class ColumnListExtensions
{
public static ToColumnList(this IEnumerable<Column> collection)
{
return new ColumnList(collection);
}
}
var cols = othercolumnlist.Select(c => new Column { Name = c.Name })
.ToColumnList();
What you are trying to do is down-cast List<Column>
to ColumnList
which assumes that all List<T>
's are ColumnList
's - which obviously they aren't.
What you can do however is initialize a new instance of ColumnList
by passing the result of your query
new ColumnList().AddRange(othercolumnlist
.Select(x => new Column { Name = x.Name })
.ToList());
You could if you define a copy constructor for your ColumnList
type:
public class ColumnList : List<Column>
{
public ColumnList(IEnumerable<Column> src) : base(src)
{
}
}
And you then do:
var cols = new ColumnList(from c in othercolumnlist
select new Column
{
Name = c.Name,
}).ToList());
Reason being ToList()
returns a List
and not a ColumnList
. It can only ever be a ColumnList
if you explicitly instantiate it as one, but never vice-versa.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.