Методы внутри org.apache.commons.io.FileUtils
также могут быть очень удобными, например :
/**
* Reads the contents of a file line by line to a List
* of Strings using the default encoding for the VM.
*/
static List readLines(File file)
Вы не можете придать его (сохраняя ссылочный идентификатор) - это будет небезопасно. Например:
public interface IFruit {}
public class Apple : IFruit {}
public class Banana : IFruit {}
...
List<Apple> apples = new List<Apple>();
List<IFruit> fruit = apples; // Fortunately not allowed
fruit.Add(new Banana());
// Eek - it's a banana!
Apple apple = apples[0];
Теперь вы можете преобразовать List<Apple>
в IEnumerable<IFruit>
в .NET 4 / C # 4 из-за ковариации, но если вы хотите List<IFruit>
, вам придется создайте новый список. Например:
// In .NET 4, using the covariance of IEnumerable<T>
List<IFruit> fruit = apples.ToList<IFruit>();
// In .NET 3.5
List<IFruit> fruit = apples.Cast<IFruit>().ToList();
Но это not то же самое, что и приведение исходного списка, потому что теперь есть два отдельных списка. Это безопасно, но вам нужно понять, что изменения, внесенные в один список , не будут отображаться в другом списке. (Модификации объектов , которые будут отображаться в списках, конечно.)
Итератор роли и .ToList ():
List<IDic> casted = input.Cast<IDic>().ToList()
выполнит трюк.
Первоначально я сказал, что ковариация будет работать, но, как справедливо указал Джон; нет, это не будет!
И изначально я тоже тупо остановился на ToList()
вызове
Cast
возвращает IEnumerable<T>
, а не List<T>
- и нет, ковариация не будет i> разрешать это преобразование, потому что это будет небезопасно - см. мой ответ.
– Jon Skeet
19 January 2012 в 13:41
ToList()
отсутствует, прежде чем читать ваш комментарий; но да, как вы показали, конечно, Ковариация не сработает! Doh!
– Andras Zoltan
19 January 2012 в 13:44
Cast
в .NET 4, если вы указываете аргумент типа ToList
.
– Jon Skeet
19 January 2012 в 13:45
В .Net 3.5 вы можете сделать следующее:
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
Конструктор List в этом случае принимает IEnumerable. хотя он только конвертируется в IEnumerable. Несмотря на то, что myObj может быть конвертируемым в ISomeInterface, тип IEnumerable не конвертируется в IEnumerable.
List<Client> listOfA = new List<Client>();
List<IDic> list = listOfA.Cast<IDic>().ToList();
Если вы можете использовать LINQ, тогда вы можете это сделать ...
List<Client> clientList = new List<Client>();
List<IDic> list = clientList.Select(c => (IDic)c).ToList();
Это возможно только путем создания нового List<IDic>
и переноса всех элементов.
У меня тоже была эта проблема, и после прочтения ответа Джона Скита я изменил свой код с помощью List<T>
, чтобы использовать IEnumerable<T>
. Хотя это не отвечает исходному вопросу OP о . Как я могу отбросить List<Client>
до List<IDic>
, он избегает необходимости этого и, следовательно, может быть полезен другим, кто сталкивается с этой проблемой. Это, конечно, предполагает, что код, требующий использования List<IDic>
, находится под вашим контролем.
Например:
public void ProcessIDic(IEnumerable<IDic> sequence)
{
// Implementation
}
Вместо:
public void ProcessIDic(List<IDic> list)
{
// Implementation
}
List<IFruit>
, которая на самом деле была ссылкой наList<Apple>
. Что бы вы ожидали, если бы вы добавили ссылкуBanana
к этомуList<IFruit>
? – Jon Skeet 20 December 2014 в 10:50using
дляSystem.Linq
или то, что вы пытаетесь вызвать, я не уверен, как вы ожидаете, что я смогу помочь. Я предлагаю вам сделать больше исследований, и если вы все еще застряли, задайте вопрос с помощью примера Minimal, Complete и Verifiable . – Jon Skeet 30 July 2017 в 06:54