문제

방금 C#의 다차원 배열이 구현되지 않는다는 것을 알았습니다. IEnumerable<T>, 구현하는 동안 IEnumerable. 단일 차원 배열의 경우 IEnumerable<T> 그리고 IEnumerable 구현됩니다.

왜이 차이인가? 다차원 배열 인 경우 IEnumerable, 분명히 일반 버전도 구현해야합니까? 다차원 배열에서 확장 방법을 사용하려고했기 때문에 이것을 발견했습니다. Cast<T> 또는 유사한; 따라서 다차원 배열을 구현하는 데 대한 논쟁을 확실히 볼 수 있습니다. IEnumerable<T>.

코드에서 내 질문을 명확히하기 위해 다음 코드가 인쇄 할 것으로 예상됩니다. true 실제로 인쇄하는 동안 네 번 true, false, true, true:

int[] singleDimensionArray = new int[10];
int[,] multiDimensional = new int[10, 10];

Debug.WriteLine(singleDimensionArray is IEnumerable<int>);
Debug.WriteLine(multiDimensional is IEnumerable<int>);
Debug.WriteLine(singleDimensionArray is IEnumerable);
Debug.WriteLine(multiDimensional is IEnumerable);
도움이 되었습니까?

해결책

CLR에는 두 가지 종류의 배열이 있습니다. 벡터 이는 0의 하한 경계를 가진 1 차원 및 0 이외의 경계가 있고 0 이외의 순위를 가질 수있는 더 많은 일반 어레이로 보장됩니다.

CLI 사양의 8.9.1 절에서 :

또한 요소 유형 T가있는 생성 된 벡터는 인터페이스를 구현합니다. System.Collections.Generic.IList<U>(§8.7), 여기서 U : = T.

나는 그것이 나에게 꽤 이상해 보인다고 말해야한다. 이미 구현된다는 점을 감안할 때 IEnumerable 왜 구현해서는 안되는지 모르겠습니다 IEnumerable<T>. 구현하는 것은 의미가 없습니다 IList<T>, 그러나 간단한 일반 인터페이스는 괜찮을 것입니다.

당신이 이것을 원한다면, 당신은 전화 할 수 있습니다 Cast<T> (.NET 3.5를 사용하는 경우) 또는 배열을 통해 반복하기 위해 자신만의 방법을 작성하십시오. 캐스팅을 피하기 위해 각 차원의 낮은/상한을 발견하고 그런 식으로 가져온 방법을 찾아야합니다. 굉장히 즐겁지 않습니다.

다른 팁

해결 방법이 있습니다. 다차원 배열을 ienumerable로 변환 할 수 있습니다.

public static class ArrayExtensions
{
    public static IEnumerable<T> ToEnumerable<T>(this Array target)
    {
        foreach (var item in target)
            yield return (T)item;
    }
}

다차원 배열입니다 ~ 아니다 상속 계층의 목적을위한 배열. 그것들은 완전히 별도의 유형입니다. 또한이 유형은 두 가지 가능한 이유로 프레임 워크에서 좋은 지원을받지 않습니다.

  • 실제로 그렇게 유용하지 않습니다. 다차원 배열에 대한 유일한 실제 사용은 행렬입니다. 거의 모든 것에 대해 다른 데이터 구조 (예 : 들쭉날쭉 한 배열)가 더 적합합니다.
  • 이러한 구조에 대한 일반적이고 유용한 방법을 고안하는 것은 사소한 일이 아닙니다.

의 경우 IEnumerable, 이것이 어떻게 구현되어야 했는가, 즉 요소가 열거되어야하는 순서는 무엇입니까? 다차원 배열에 내재 된 순서는 없습니다.

제로 결합 단일 치수 배열은 두 가지를 구현합니다 IEnumerable 그리고 IEnumerable<T>, 그러나 다차원 배열은 불행히도 구현됩니다 IEnumerable. @jader dias의 "해결 방법"은 실제로 다차원 배열을 IEnumerable<T> 그러나 큰 비용으로 : 배열의 모든 요소는 박스가됩니다.

다음은 모든 요소에 대한 권투를 유발하지 않는 버전입니다.

public static class ArrayExtensions
{
    public static IEnumerable<T> ToEnumerable<T>(this T[,] target)
    {
        foreach (var item in target)
            yield return item;
    }
}

들쭉날쭉 한 배열은 지원하지 않습니다 IEnumerable<int> 다차원 구조는 실제로 유형의 배열이 아니기 때문에 유형의 배열입니다.

int[] singleDimensionArray = new int[10];
int[][] multiJagged = new int[10][];

Debug.WriteLine(singleDimensionArray is IEnumerable<int>);
Debug.WriteLine(multiJagged is IEnumerable<int[]>);
Debug.WriteLine(singleDimensionArray is IEnumerable);
Debug.WriteLine(multiJagged is IEnumerable);

진실, 진실, 진실, 진실을 인쇄합니다.

메모: int[,] 그렇지 않습니다 IEnumerable<int[]>, 그것은 다른 답변에 명시된 이유, 즉 반복 할 차원을 알 수있는 일반적인 방법이 없습니다. 들쭉날쭉 한 배열의 경우 구문이 배열 배열이라는 것에 대해 구문이 분명하기 때문에 해석의 여지가 많지 않습니다.

반대로 생각하십시오. 2D 배열은 이미 존재합니다. 그냥 열거하십시오. 중복 값을 포함하여 초기 배열 또는 마크의 점수 및 장소가있는 2D 배열을 만듭니다.

int[] secondmarks = {20, 15, 31, 34, 35, 50, 40, 90, 99, 100, 20};

IEnumerable<int> finallist = secondmarks.OrderByDescending(c => c);

int[,] orderedMarks = new int[2, finallist.Count()];

Enumerable.Range(0, finallist.Count()).ToList().ForEach(k => {orderedMarks[0, k] = (int) finallist.Skip(k).Take(1).Average();
orderedMarks[1, k] = k + 1;}); 

Enumerable.Range(0, finallist.Count()).Select(m => new {Score = orderedMarks[0, m], Place = orderedMarks[1, m]}).Dump();

결과:

Score Place

100     1
99      2 
90      3 
50      4 
40      5 
35      6    
34      7    
31      8    
20      9     
20     10 
15     11 
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top