public class SomeDataCollection : List<ISomeData>
{
// some method ...
}
но я не могу этого сделать:
SomeDataCollection someDatas = new List<ISomeData>();
Невозможно неявно преобразовать тип List<ISomeData> в SomeDataCollection. Существует явное преобразование (вам не хватает приведения?)
поэтому я пытаюсь создать неявное покрытие внутри класса коллекции SomeDataCollection:
public static implicit operator SomeDataCollection(List<ISomeData> l)
{
var someDatas = new SomeDataCollection();
someDatas.AddRange(l);
return someDatas;
}
но он сказал, что я не могу создать такой конвертер:
SomeDataCollection.implicit operator SomeDataCollection(List<ISomeData>): определяемые пользователем преобразования в базовый класс или из него запрещены
new List<ISomeData>(); по-прежнему остается просто List<ISomeData>. Это не SomeDataCollection. Суть создания подкласса заключается в том, что подкласс может иметь дополнительное состояние и т. Д., Но объект (однажды созданный) никогда не меняет тип.
Вам не разрешено создавать операторы между типами в одной иерархии, так как это нарушит обычное и ожидаемое поведение приведения типов.
Вы можете просто использовать:
var data = new SomeDataCollection();
Однако я должен добавить, что, откровенно говоря, подкласс List<T> редко бывает полезным. Не в последнюю очередь, он не предоставляет никаких полезных virtual методов, поэтому вы не можете настроить поведение. Честно говоря, я бы просто использовал List<ISomeData> (и полностью удалил SomeDataCollection), если у меня нет ясной и очевидной цели для этого. А затем: я мог бы инкапсулировать список или унаследовать от Collection<T>.
Вы всегда можете просто добавить метод как метод расширения?
public static class Utils {
public static void SomeMethod(this IList<ISomeData> list) {
...
}
}
тогда:
var list = new List<ISomeData>();
...
list.SomeMethod();
Ответ 2 · рейтинг 2 · penartur
Прежде всего, почему вы хотите записать new List<ISomeData> в переменную, определенную как SomeDataCollection? Возможно, вы действительно хотели SomeDataCollection someDatas = new SomeDataCollection();
Что касается сообщений об ошибках, первое сообщение об ошибке сообщает вам, что List<ISomeData> не является производным от SomeDataCollection, поэтому вы не можете делать с ним то, что делали бы с SomeDataCollection, поэтому вы не можете записать его в переменную, которая определена как SomeDataCollection ( представьте, например, если бы в SomeDataCollection было public void someMethod(), а позже в коде вы бы назвали someDatas.someMethod()).
Второе сообщение об ошибке сообщает вам, что преобразователи предназначены для преобразования между совершенно разными типами, а не между базовым и производным типами. В противном случае, что вы ожидаете получить, например, в следующем примере:
SomeDataCollection a = new SomeDataCollection();
List<ISomeData> b = (List<ISomeData>)a;
SomeDataCollection c = (SomeDataCollection)b;
Он должен вызывать ваш конвертер или нет?
В основном код, который вы пытаетесь написать, очень неправильный для начала, поэтому нам нужно знать, что вы пытаетесь сделать, и тогда, возможно, мы сможем сказать вам решение вашей корневой проблемы (а не проблемы "как сделать компиляцию этого кода").
Ответ 3 · рейтинг 2 · Anders Gustafsson
Не лучше ли реализовать конструктор в SomeDataCollection?
public SomeDataCollection() : base() { }
Конечно, это можно было бы дополнить
public SomeDataCollection(IEnumerable<ISomeData> collection)
: base(collection) { }
Тогда вы сможете инициализировать свой SomeDataCollection следующим образом:
SomeDataCollection someData = new SomeDataCollection();
SomeDataCollection someOtherData =
new SomeDataCollection(collectionOfSomeData);
и по-прежнему иметь доступ ко всем общедоступным методам и свойствам в List<ISomeData>.
Ответ 4 · Eugene
Это не проблема с дженериками. В C # вам не разрешено явно преобразовывать базовый класс в производный класс.