2008-09-11 8 views
10

어쩌면 bizare 일을하고 싶지만, .Net의 하한> 0 인 배열을 만들어야합니다.. 하한> 0 인 Net 배열.

Array.CreateInstance(typeof(Object), new int[] {2}, new int[] {9}); 

원하는 결과 (하한이 9로 설정된 객체의 배열)를 생성합니다. 그러나 생성 된 배열 인스턴스는 더 이상 Object[]을 기다리고있는 다른 메서드로 전달할 수 없습니다.

System.Object[*]System.Object[]으로 캐스트 할 수 없습니다. 배열 유형에서이 차이점은 무엇이며이를 어떻게 극복 할 수 있습니까?

편집 : 실패 테스트 코드 =

Object x = Array.CreateInstance(typeof(Object), new int[] {2}, new int[] {9}); 
Object[] y = (Object[])x; 

는 "유형의 개체를 캐스팅 할 수 없습니다 '으로 System.Object [*]' '으로 System.Object []'입력합니다."

또한 여러 차원을 사용하는 경우이 방법 작업을 않습니다 싶습니다 : 잘 작동

Object x = Array.CreateInstance(typeof(Object), new int[] {2,2}, new int[] {9,9}); 
Object[,] y = (Object[,])x; 

합니다.

답변

2
+0

불행히도 @PaulV는 [자신의 오래된 블로그 게시물을 삭제] (http://panopticoncentral.net/2011/03/29/external-requests-versus-internal-requirements/)하기로 결정 했으므로 이제는 죽은 링크입니다. –

+0

@MarkHurd 인터넷 웨이백 머신을 구출하십시오! [VB가 배열의 0이 아닌 하한을 지원하지 않는 이유는 무엇입니까?] (http://web.archive.org/web/20100306164952/http://www.panopticoncentral.net/articles/950.aspx) – Xantham

+0

@Xantham 예, PaulV는 [실수를 깨달았습니다.] (http://www.panopticoncentral.net/2012/10/02/undoing-some-of-the-damage/) 이러한 기사를 복원했습니다. [0이 아닌 하한 배열 동전의 다른면]] (http://www.panopticoncentral.net/2004/03/17/non-zero-lower-bounded-arrays-the-other-side-of-the-coin/). –

1

Object []로 전달할 수없는 이유는 확실치 않지만 배열을 래핑하고 거기에 "이상한 논리"를 처리하기 위해 실제 클래스를 만드는 경우 쉽지 않을 것입니다.

클래스에 "정보"를 추가 할 수 있다면 실제 참조 개체를 사용하면 얻을 수있는 이점을 얻을 수 있습니다.

편집 : 배열을 어떻게 형변환합니까? 더 많은 코드를 게시 할 수 있습니까? 감사.

+0

포장하는 것이 좋겠지 만 특정 이유로 인해 특정 상황에서 피할 필요가 있습니다. 나는 더 많은 코드로 편집 할 것이다. – DAC

3

당신이 다른 하나에서 캐스팅 할 수없는 이유는이 악한 것입니다.

개체의 배열 [5..9]을 만들고 개체 F로 함수 F에 전달한다고 가정 해 보겠습니다.

함수가 5.9인지 어떻게 알 수 있습니까? F는 일반적인 배열을 기대하고 있지만 제한된 배열을 얻고 있습니다. 당신은 그것이 가능하다는 것을 알 수 있다고 말할 수 있지만 이것은 예상치 못한 일이며 사람들은 간단한 배열을 사용하고자 할 때마다 모든 종류의 경계 검사를하고 싶지 않습니다.

배열은 프로그래밍에서 가장 단순한 구조이므로 너무 복잡해서 사용할 수 없게 만듭니다. 다른 구조가 필요할 것입니다.

당신이해야 할 일은 원하는 동작을 모방 한 제한된 컬렉션 인 클래스입니다. 그렇게하면 해당 클래스의 모든 사용자는 무엇을 기대해야하는지 알 수 있습니다.

class ConstrainedArray<T> : IEnumerable<T> where T : new() 
{ 
    public ConstrainedArray(int min, int max) 
    { 
     array = new T[max - min]; 
    } 

    public T this [int index] 
    { 
     get { return array[index - Min]; } 
     set { array[index - Min] = value; } 
    } 

    public int Min {get; private set;} 
    public int Max {get; private set;} 

    T[] array; 

    public IEnumerator<T> GetEnumerator() 
    { 
     return array.GetEnumarator(); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return array.GetEnumarator(); 
    } 

} 
+0

코드 스 니펫을 보내 주셔서 감사합니다. 그러나이 문제는 많은 양의 코드에서 하한> 0을 예상하는 VB6 마이그레이션 문제에서 발생하므로 필요한 경우 모든 유형의 줄 바꿈을 피하기를 원합니다. 따라서 처음에는 if first를 확인하기 위해 최선을 다하고 있습니다. if 사용자 정의 클래스를 사용하지 않을 수도 있습니다. – DAC

+0

특정 사례에 대한 설명이 의미있는 동안, 나는 귀하의 말씨에 동의하지 않습니다. 파스칼 배경에서 .NET으로 옮긴 후 "일반 배열"또는 "단순 배열"은 항상 임의의 시작 색인이있는 항목이었습니다. C#은 다르게 보지만 .NET과 같은 다중 언어 플랫폼을 사용하여 "모든 종류의 경계 검사"를 생략 할 수있는 변명이 될 수는 없습니다. 결국 배열의 길이에 대한 경계 검사 (암시 적으로 허용되는 색인 값의 상한)는 C#에도 있어야합니다. 그럼에도 불구하고 좋은 래퍼 클래스. –

1

const 오프셋 정수에 하한값을 저장하고 원본 값이 인덱스로 반환하는 값에서 해당 값을 뺍니다.

또한 이전 VB6 기능입니다. 나는 그것을 뒷받침하는 속성이있을 것이라고 생각합니다.