[]를 사용하여 인덱싱을 'System.Collections.Generic.IEnumerable <> 형식의 식에 적용 할 수 없습니다.
IEnumerable에서 인덱싱이 허용되지 않는 특별한 이유가 있습니까?
내가 가진 문제에 대한 해결 방법을 찾았지만 인덱싱을 허용하지 않는 이유를 알고 싶습니다.
감사,
아니기 때문에.
인덱싱은 IList
. IEnumerable
"IList의 일부 권한이 있지만 전부는 아닙니다."를 의미합니다.
일부 컬렉션 (예 : 연결 목록)은 실용적인 방식으로 인덱싱 할 수 없습니다. 그러나 항목별로 액세스 할 수 있습니다. IEnumerable
그런 컬렉션을위한 것입니다. 컬렉션은 IList 및 IEnumerable (및 기타 여러 항목)을 모두 구현할 수 있습니다. 일반적으로 IEnumerable
함수 매개 변수 로만 찾을 수 있습니다. 즉, 가장 간단한 액세스 모드 만 있으면 함수가 모든 종류의 컬렉션을받을 수 있습니다.
IEnumerable<T>
인터페이스는 포함되지 않습니다 인덱서를 , 당신은 아마 그것을 혼동하고IList<T>
객체가 실제로 IList<T>
(예 : List<T>
또는 배열 T[]
) 인 경우 해당 유형에 대한 참조도 만들어보십시오 IList<T>
.
그렇지 않으면 Enumerable.ElementAt 확장 메서드 myEnumerable.ElementAt(index)
를 사용하는 것을 사용할 수 있습니다 . 이것은 모든에 대해 작동합니다 . (런타임) 객체가를 구현하지 않으면 모든 첫 번째 항목이 열거되고 마지막 항목을 제외한 모든 항목이 삭제됩니다.IEnumerable<T>
IList<T>
index + 1
편집 : 설명으로 IEnumerable<T>
"열거를 노출하는 것"을 나타내는 인터페이스입니다. 구체적인 구현은 물론 메모리 목록 어떤 종류의 수 있습니다 않는 인덱스에 의해 빠른 액세스를 허용하거나하지 않을 수 있습니다. 예를 들어, 연결된 목록 (James Curran이 언급 한대로)과 같이 이러한 쿼리를 효율적으로 충족 할 수없는 컬렉션 일 수 있습니다. 요구에 따라 항목이 생성 ( '수율')되는 반복 기나 원격 데이터 소스에서 항목을 가져 오는 열거 자에 의해 생성되는 반복기와 같은 일종의 인 메모리 데이터 구조 가 아닐 수도 있습니다 . 때문에 IEnumerable<T>
모든 경우를 지원해야합니다, 인덱서는 그 정의에서 제외됩니다.
한 가지 이유는 IEnumerable
에 알 수없는 수의 항목이 포함되어 있기 때문일 수 있습니다 . 일부 구현에서는 항목을 반복 할 때 항목 목록을 생성합니다 ( yield
샘플 참조 ). 인덱스를 사용하여 항목에 액세스 할 때는 잘 작동하지 않습니다. 목록에 최소한 그 정도의 항목이 있다는 것을 알아야합니다.
열거 가능한 유형이 아래와 같은 문자열이면 인덱싱을 사용할 수 있습니다.
((string[])MyEnumerableStringList)[0]
[]-연산자는 this[sometype index]
Element- Collection에 따라 구현 되는 access 속성으로 확인됩니다 .
Enumerable-Interface는 처음에 컬렉션이 어떻게 생겼는지에 대한 청사진 을 선언합니다 .
다음 예제를 통해 깨끗한 인터페이스 분리 의 유용성을 입증하십시오 .
var ienu = "13;37".Split(';').Select(int.Parse);
//provides an WhereSelectArrayIterator
var inta = "13;37".Split(';').Select(int.Parse).ToArray()[0];
//>13
//inta.GetType(): System.Int32
또한 []-연산자 의 구문을 보십시오 .
//example
public class SomeCollection{
public SomeCollection(){}
private bool[] bools;
public bool this[int index] {
get {
if ( index < 0 || index >= bools.Length ){
//... Out of range index Exception
}
return bools[index];
}
set {
bools[index] = value;
}
}
//...
}
ToList 를 사용 하여 목록으로 변환 할 수 있습니다 . 예를 들면
SomeItems.ToList()[1]
인터페이스의 개념은 일반적으로 개체에 대해 작업을 수행하는 코드가 해당 개체에서 제공하는 특정 기능을 보장 할 수있는 일종의 기본 계약을 노출하는 것입니다. 의 경우 IEnumerable<T>
계약은 "내 모든 요소에 하나씩 액세스 할 수 있습니다."
이 계약만으로 작성할 수있는 방법은 많습니다. 수많은 예제 Enumerable
를 보려면 클래스를 참조하십시오 .
But to zero in on just one concrete one: think about Sum
. In order to sum up a bunch of items, what do you need? What contract would you require? The answer is quite simple: just a way to see every item, no more. Random access isn't necessary. Even a total count of all the items is not necessary.
To have added an indexer to the IEnumerable<T>
interface would have been detrimental in two ways:
- Code that requires the contract described above (access to a sequence of elements), if it required the
IEnumerable<T>
interface, would be artificially restrictive as it could not deal with any type that did not implement an indexer, even though to deal with such a type should really be well within the capabilities of the code. - Any type that wanted to expose a sequence of elements but was not appropriately equipped to provide random access by index (e.g.,
LinkedList<T>
,Dictionary<TKey, TValue>
) would now have to either provide some inefficient means of simulating indexing, or else abandon theIEnumerable<T>
interface.
All this being said, considering that the purpose of an interface is to provide a guarantee of the minimum required functionality in a given scenario, I really think that the IList<T>
interface is poorly designed. Or rather, the lack of an interface "between" IEnumerable<T>
and IList<T>
(random access, but no modification) is an unfortunate oversight in the BCL, in my opinion.
'IT Share you' 카테고리의 다른 글
Oracle JDBC 간헐적 연결 문제 (0) | 2020.12.07 |
---|---|
읽기 전용 자동 구현 속성이 가능합니까? (0) | 2020.12.07 |
정규식 일치 후 다음 텍스트 가져 오기 (0) | 2020.12.07 |
Android, 옵션 메뉴 생성 방법 (0) | 2020.12.07 |
MySQL my.cnf 파일-이전 그룹이없는 옵션을 찾았습니다. (0) | 2020.12.07 |