У меня есть следующие классы:
public class Column
{
public String Name;
public String Value;
}
public class ColumnList : List<Column> {}
Тогда я делаю:
var cols = (from c in othercolumnlist
select new Column
{
Name = c.Name,
}).ToList() as ColumnList;
Однако он возвращает null. Как я могу успешно добавить в свой список?
4 ответа
То, что вы пытаетесь сделать, эквивалентно этому:
Animal animal = new Animal();
Dog dog = animal as Dog;
Одно из возможных решений - предоставить конструктор, который принимает существующий список и вызывает базовый конструктор, например:
public class ColumnList : List<Column>
{
public ColumnList(IEnumerable<Column> collection):
base(collection)
{
}
}
А затем создайте свой ColumnList
из существующей коллекции.
var collection = othercolumnlist.Select(c => new Column { Name = c.Name });
var columnList = new ColumnList(collection);
Вы также можете предоставить метод расширения, чтобы упростить это:
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();
ColumnList
- это List<Column>
, но List<Column>
не ColumnList
. Рассмотрим классы Animal
и Dog
:
public class Animal
{
}
public class Dog: Animal
{
}
Вы пытаетесь относиться к любому животному как к собаке. Но не все животные - собаки. Может быть Cat
или Kangaroo
. Вот почему as ColumnList
возвращает null
.
Вместо этого вам нужно создать новый экземпляр ColumnList
и добавить в него столбцы вручную:
var columnList = new ColumnList();
columnList.AddRange(othercolumnlist.Select(c => new Column { Name = c.Name }));
Если вам нужно делать это часто, вы можете добавить статический метод создания в свой класс ColumnList
:
public static ColumnList CreateFrom(ColumnList other)
{
var columnList = new ColumnList();
columnList.AddRange(other.Select(c => new Column { Name = c.Name }));
return columnList;
}
И используйте это так:
var columnList = ColumnList.CreateFrom(otherColumnList);
То, что вы пытаетесь сделать, - это преобразовать List<Column>
в ColumnList
, что предполагает, что все List<T>
являются ColumnList
, а это, очевидно, не так.
Однако вы можете инициализировать новый экземпляр ColumnList
, передав результат вашего запроса
new ColumnList().AddRange(othercolumnlist
.Select(x => new Column { Name = x.Name })
.ToList());
(object)"Hello world"
string
происходит от object
, поэтому ваш пример не повышает, а понижает (что совершенно законно). Повышение приведения будет происходить var obj = new object(); string str = (string)obj
- и хотя это сработает, string
- это особый тип объекта, и среда CLR обрабатывает его по-разному.
Вы могли бы, если бы вы определили конструктор копирования для вашего типа ColumnList
:
public class ColumnList : List<Column>
{
public ColumnList(IEnumerable<Column> src) : base(src)
{
}
}
И тогда вы делаете:
var cols = new ColumnList(from c in othercolumnlist
select new Column
{
Name = c.Name,
}).ToList());
Причина, по которой ToList()
возвращает List
, а не ColumnList
. Это может быть только ColumnList
, если вы явно создаете его как один, но никогда не наоборот.
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.
List<T>
?? вы также можете увидеть этот вопрос stackoverflow.com/questions/5376203/inherit-listtToList
из BCL вернуть экземпляр вашего пользовательского классаColumnList
(на что вы надеетесь, применяя операторas
)?