[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에 영향을 미치지 않습니다. 이것은 적어도 두 가지 이유로 대부분의 경우에 정확합니다. 이것은 한 영역의 변경이 다른 영역에 영향을 미치는 (느슨한 결합)을 방지하는 데 도움이되며 컴파일러 문제로 코드를 설계해서는 안되므로 매우 읽기 쉽습니다.
그러나 타이트한 루프에 있거나 임베디드 또는 메모리 부족 시스템에서 작업하는 것과 같은 특정 인스턴스가 있으며 컴파일러 고려 사항을 고려해야합니다.