[c#] List <T>와 IEnumerable <T>간에 자유롭게 변환

a List<MyObject>를 로 변환 한 IEnumerable<MyObject>다음 다시 되돌리려면 어떻게해야합니까?

목록에서 일련의 LINQ 문을 실행하기 위해이 작업을 수행하고 싶습니다. Sort()



답변

List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myEnumerable.ToList();


답변

A List<T>IEnumerable<T>이므로 실제로 a List<T>를 .txt로 ‘변환’할 필요가 없습니다 IEnumerable<T>. a List<T>는 이므로 IEnumerable<T>단순히 List<T>유형의 변수에 a 를 할당 할 수 있습니다 IEnumerable<T>.

반대로 모든 IEnumerable<T>것이 List<T>오프 코스가 아니므로 .NET Framework의 ToList()멤버 메서드 를 호출해야 합니다 IEnumerable<T>.


답변

A List<T>는 이미 IEnumerable<T>이므로 List<T>변수에서 직접 LINQ 문을 실행할 수 있습니다 .

LINQ 확장 메서드 OrderBy()가 보이지 않으면 using System.Linq소스 파일에 지시문 이 없기 때문이라고 생각 합니다.

하지만 LINQ 식 결과를 다시 List<T>명시 적으로 다시 변환해야합니다 .

List<Customer> list = ...
list = list.OrderBy(customer => customer.Name).ToList()


답변

참고 : 표준 LINQ 연산자 (이전 예제에 따라)는 기존 목록을 변경하지 않고 list.OrderBy(...).ToList()순서가 변경된 시퀀스를 기반으로 새 목록을 만듭니다. 그러나 List<T>.Sort다음 과 함께 람다를 사용할 수있는 확장 메서드를 만드는 것은 매우 쉽습니다 .

static void Sort<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(x), selector(y)));
}

static void SortDescending<TSource, TValue>(this List<TSource> list,
    Func<TSource, TValue> selector)
{
    var comparer = Comparer<TValue>.Default;
    list.Sort((x,y) => comparer.Compare(selector(y), selector(x)));
}

그런 다음 다음을 사용할 수 있습니다.

list.Sort(x=>x.SomeProp); // etc

이렇게 하면 일반적으로 수행 하는 것과 동일한 방식으로 기존 목록 이 업데이트됩니다 List<T>.Sort.


답변

변환 List<T>IEnumerable<T>

List<T>를 구현 IEnumerable<T>(및 기타 여러 IList<T>, ICollection<T>)하므로 List를 IEnumerable로 다시 변환 할 필요가 없습니다 IEnumerable<T>.

예:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Person person1 = new Person() { Id = 1, Name = "Person 1" };
Person person2 = new Person() { Id = 2, Name = "Person 2" };
Person person3 = new Person() { Id = 3, Name = "Person 3" };

List<Person> people = new List<Person>() { person1, person2, person3 };

//Converting to an IEnumerable
IEnumerable<Person> IEnumerableList = people;

Enumerable.AsEnumerable()방법 을 사용할 수도 있습니다

IEnumerable<Person> iPersonList = people.AsEnumerable();

변환 IEnumerable<T>List<T>

IEnumerable<Person> OriginallyIEnumerable = new List<Person>() { person1, person2 };
List<Person> convertToList = OriginallyIEnumerable.ToList();

이것은 Entity Framework 에서 유용합니다 .


답변

메모리 중복을 방지하기 위해 resharper는 다음을 제안합니다.

List<string> myList = new List<string>();
IEnumerable<string> myEnumerable = myList;
List<string> listAgain = myList as List<string>() ?? myEnumerable.ToList();

.ToList ()는 새로운 불변 ​​목록을 반환합니다. 따라서 listAgain을 변경해도 @Tamas Czinege 답변의 myList에 영향을 미치지 않습니다. 이것은 적어도 두 가지 이유로 대부분의 경우에 정확합니다. 이것은 한 영역의 변경이 다른 영역에 영향을 미치는 (느슨한 결합)을 방지하는 데 도움이되며 컴파일러 문제로 코드를 설계해서는 안되므로 매우 읽기 쉽습니다.

그러나 타이트한 루프에 있거나 임베디드 또는 메모리 부족 시스템에서 작업하는 것과 같은 특정 인스턴스가 있으며 컴파일러 고려 사항을 고려해야합니다.


답변