IEnumerable
과 의 차이점은 무엇입니까 Array
?
IList
과 의 차이점은 무엇입니까 List
?
이것들은 같은 기능을하는 것 같습니다.
답변
IEnumerable은 최소한의 “반복 가능”기능 만 제공합니다. 시퀀스를 순회 할 수 있지만 그게 전부입니다. 예를 들어 IEnumerable을 사용하여 요소를 계산하거나 n 번째 요소를 얻는 것은 매우 비효율적이지만 장점도 있습니다. 예를 들어 IEnumerable은 소수의 시퀀스처럼 무한 시퀀스가 될 수 있습니다.
배열은 임의 액세스가 가능한 고정 크기 모음입니다 (즉, 색인화 할 수 있음).
목록은 임의 액세스가 가능한 가변 크기 모음입니다 (즉, 요소를 추가 및 제거 할 수 있음).
IList는 List, BindingList, ObservableCollection 등과 같은 다양한 구체적인 클래스에서 떨어져 목록 기능 (계수, 추가, 제거, 인덱서 액세스)을 추상화하는 인터페이스입니다.
답변
IEnumerable은 항목 컬렉션 (예 : foreach 키워드를 통해)을 통한 반복을 허용하는 인터페이스입니다.
배열은 .NET 내장입니다. 동일한 유형의 항목을 보관하지만 크기는 고정되어 있습니다. x 요소로 배열을 만들면 확장하거나 축소 할 수 없습니다.
IList는 목록에 대한 인터페이스를 정의하고 IEnumerable도 구현합니다.
List는 IList 인터페이스를 구현합니다. 구체적인 유형의 목록입니다.
.NET 목록과 배열의 차이점은 목록에 요소를 추가 할 수 있다는 것입니다. 목록은 필요한 모든 항목을 포함 할 수있을만큼 커질 수 있습니다. 목록은이를 내부적으로 배열에 저장하고 배열이 더 이상 모든 요소를 담을만큼 크지 않으면 새 배열이 생성되고 항목이 복사됩니다.
IList 및 배열은 모두 IEnumerable을 구현합니다. 그것이 인터페이스가 작동하는 방식입니다. 인터페이스 등에 대해 읽어 보는 것이 좋습니다.
답변
IEnumerable 및 IList는 인터페이스 입니다. 배열과 목록은 클래스입니다. 배열은 IEnumerable을 구현합니다. List는 IEnumerable을 확장하는 IList를 구현합니다.
편집 : itowlson이 주석에서 언급했듯이 Array는 IList도 구현합니다.
답변
IEnumerable 컬렉션 생성이 지연됩니다. 예:
public IEnumerable<int> GetTwoInts()
{
yield return 1;
yield return 2;
}
public void Something()
{
var twoInts = GetTwoInts();
}
Something 메서드에서 GetTwoInts ()에 대한 호출은 열거가 반복되지 않기 때문에 실제로 GetTwoInts 메서드가 실행되지 않습니다.
답변
IEnumerable
같은 많은 클래스에 의해 사용되는 범용 인터페이스 Array
, List
및 String
수집을 통해 누군가의 반복 처리를하도록하기 위해서이다. 기본적으로 foreach
성명서 의 원동력 입니다.
IList
일반적으로 유형의 변수 List
를 최종 사용자에게 노출하는 방법 입니다. 이 인터페이스는 기본 컬렉션에 대한 임의 액세스를 허용합니다.
답변
다른 답변을 보완하기 위해 와 사이에 성능 차이 가 있습니다.IList<T>
List<T>
foreach 문을 실행할 때 실행할 때 있습니다.
에서 반환 된 반복기 개체 List<T>.GetEnumerator
는 값 형식이고에서 반환 된 개체 IList<T>.GetEnumerator
는 참조 형식이므로 메모리 할당이 필요하기 때문 입니다 (c #의 목록 값 형식 열거 자 참조) . ).
제 생각에는 IList<T>
어쨌든 좋은 인터페이스가 아닙니다. 예를 들어 호출이 Add
발생할 수 있습니다 ( 배열이 IList를 구현하는 이유 참조 ). 캡슐화가 필요하면 IEnumerable<T>
또는 을 사용하는 것이 좋습니다 IReadOnlyList<T>
.
답변
다른 답변 외에도 LINQ를 사용할 때 Enumerable과 List / Array의 차이점을 이해하면 성능에 큰 영향을 미칠 수 있습니다. 간단히 말해 Enumerable은 쿼리 작성기로 인식 될 수있는 반면 List / Array는 쿼리의 결과입니다.
EntityFramework를 사용하는 LINQ to SQL의 컨텍스트에서 전자는 데이터베이스에 대해 실행하지 않고 SQL 쿼리를 작성하거나 메모리에 데이터를로드하지 않고 나중에는 반대입니다. 이것이 .ToList()
비즈니스 로직을 수행하기 위해 메모리에 필요할 때까지 호출을 연기하는 이유 입니다.
다른 컨텍스트에서 IEnumerable을 반환하는 LINQ 식은 .ToList()
이 호출 될 때까지 실행을 연기 합니다. 아래 예를 고려하십시오.
void Main()
{
var w1 = "AB".AsEnumerable();
Console.WriteLine($"W1: 1");
w1 = w1.Where(W1);
Console.WriteLine($"W1: 2");
w1 = w1.Where(W2);
Console.WriteLine($"W1: 3");
w1.ToList();
Console.WriteLine($"----------");
var w2 = "CD".AsEnumerable();
Console.WriteLine($"W2: 1");
w2 = w2.Where(W1);
Console.WriteLine($"W2: 2");
w2 = w2.ToList();
Console.WriteLine($"W2: 3");
w2 = w2.Where(W2);
Console.WriteLine($"W2: 4");
w2.ToList();
Console.WriteLine($"----------");
}
bool W1(char arg)
{
Console.WriteLine($"W1:{arg}");
return true;
}
bool W2(char arg)
{
Console.WriteLine($"W2:{arg}");
return true;
}
OUTPUT:
W1: 1
W1: 2
W1: 3
W1:A
W2:A
W1:B
W2:B
----------
W2: 1
W2: 2
W1:C
W1:D
W2: 3
W2: 4
W2:C
W2:D
----------
첫 번째 예에서 두 개 .Where()
는 “추가”되고 .ToList()
항목 ” A “가 먼저 파이프를 통과 한 다음 항목 ” B ” 를 통해 호출 될 때 끝에 함께 실행됩니다 . 따라서 두 번째 예에서는 ” AABB “가 출력에 표시됩니다. 그 다음 .Where()
에 .ToList()
즉시 호출하면 매번 실행 되므로 ” CD “가 표시되고 ” CD “가 다시 표시되고 두 번 출력됩니다. 따라서 Enumerable이 List 또는 Array로 변환 될 때마다 비용이 1 O (n) 컬렉션의 모든 항목에 대해 반복 이 발생하므로 컬렉션이 클 때 성능에 영향을 미칩니다.
우리가 쓰기 코드를 호출하는이 방법 추세하지 않지만 .ToList()
LINQ 통화 사이를하지만 더 자주 일어날 때 반환 재사용 가능한 방법으로 우리 요인 코드 List/Array
보다는 IEnumerable
.
그러나 이것이 우리가 항상에서 작업해야한다는 의미는 아닙니다 IEnumerable
. towlson 에서 언급했듯이 와 같은 작업 .Count()
은 컬렉션에 대한 반복을 유발하는 반면 List 또는 Array에는이 정보가 미리 계산되므로 여러 번 List/Array
호출하려는 경우 로 변환하는 것이 더 효율적 .Count()
입니다. 이것은 또한 그것을 계산 .Count
하는 .Count()
방법이 아니라 목록에 속성 이있는 이유이기도 합니다.