2009-03-12 2 views
2

배열을 사용하는 코드가 있는데, 불행히도 형식을 변경할 수 없습니다. 할 수 있다면 ArrayLists 나 simliar를 사용하여 필요한 작업을 수행 할 수는 있지만 그렇게 할 수는 없습니다. 기본적으로 정적 배열에서 객체를 추가하고 제거하는 최선의 방법을 찾고 있습니다. 즉석에서 항목을 배열에 추가하려면 이전 배열보다 큰 하나의 요소 인 새 배열을 만들고 이전 배열의 항목을 새 배열에 복사 한 다음 새 항목을 추가해야합니다. 이런 식으로 ...거기에 ArrayList와 같은 C# 정적 배열을 처리하는 방법은 무엇입니까?

public partial class dataStruct 
{ 
    private myObject[] myStaticArray; 
}; 

private void AddItemToMyArray() 
{ 
    int oldLength = dataStruct.myStaticArray.Length; 
    myObject[] newMyObjectArray = new myObject[oldLength + 1]; 
    for (int i = 0; i < oldLength; i++) 
     newMyObjectArray [i] = dataStruct.myStaticArray[i]; 

    dataStruct.myStaticArray[oldLength] = new myObject(); 
    dataStruct.myStaticArray = newMyObjectArray; 
} 

항목을 삭제하는 경우 동일한 작업을 수행하며 하나만 작게하는 새 배열을 만듭니다. 이것은 정말로 비효율적이라고 느낀다. 누구든지 더 좋은 접근법을 제안 할 수 있습니까? 또는 다른 생각?

미리 감사드립니다.

+0

. NET 2.0 이후로 배열 대신 List 을 사용할 수 있습니다. – mmmmmmmm

답변

3

왜 여기에 배열을 사용하고 싶습니까? List<T>으로 전환하거나 (가운데에서 효율적인 제거/삽입이 필요한 경우) LinkedList<T>으로 전환하십시오.

"정적"을 뜻하는 지 잘 모르겠다는 뜻입니다. 분명히 할 수 있습니까?

정보로는 Array.Resize(ref myArray, newSize)을 사용할 수 있지만 자주 변경하면 올바른 대답이 아닙니다.

+0

확장하려면 목록을 클래스에 배열이 필요한 API를 사용해야 할 때마다 호출 할 수있는 .ToArray() 메소드가 있습니다. –

+0

그가 이제는 설명 할 수 없기 때문에. = P – DevinB

6

아니요 - 배열은 항상 고정 크기입니다. 항목을 추가/삭제할 수 없습니다.

이는 정확히 ArrayListList<T>이 효과적으로 작동하는 것을 제한합니다. 내부적으로 배열을 유지하지만 일반적으로 목록의 논리 크기보다 큽니다. List<T>에 항목을 추가하면 가능한 경우 기존 배열을 채 웁니다. 충분한 공간이 없으면 더 큰 새 배열을 만들어 내용을 복사합니다. 이 변경은 발신자에게 투명합니다. 원본 참조가 아니라 목록에 대한 참조이기 때문에 원래 참조를 계속 사용할 수 있습니다.

코드 을 더 간단하게 만드는 것 중 하나는 (더 효율적이지는 않지만)은 Array.Resize을 사용하는 것입니다. 기존의 배열의 크기를 조정하지는 않지만 요청한 크기로 이전 콘텐트의 단순 복사본으로 새 배열을 반환합니다. 복사는 수동 루프보다 약간 빠르지 만 비효율의 주요 원인은 여전히 ​​존재합니다.

0

기본적으로 자신의 목록을 작성하는 것은 덜 효율적입니다.

List는 내부적으로 설명하는 것을 수행하지만 성능면에서 큰 차이점이 있습니다.

내부 배열을 재 할당 할 때 하나의 새 요소를 추가하는 것이 아니라 블록을 추가합니다. 그렇게하면 미래의 추가가 항상 재 할당을 필요로하지는 않습니다. 이것이 목록의 "용량"이며 목록 용량은 항상> 목록의 크기보다 큰 이유입니다.

이 작업을 수행해야하는 경우 비슷한 작업을 수행하는 것이 좋습니다. 그러나 목록으로 전환하는 것이 훨씬 더 좋은 방법입니다.

0

ArrayList 또는 List<T>과 같이 배열을 만들 수있는 모든 작업을 수행하면 결국 해당 클래스의 일부 또는 전부를 다시 구현하게됩니다. 가장 좋은 방법은 다른 답변과 마찬가지로 내장 클래스를 사용하는 것입니다.

2

소리에서 데이터 구조를 변경할 수 없으므로 배열을 처리해야합니다. ,

int oldLength = dataStruct.myStaticArray.Length; 
Array.Resize(dataStruct.myStaticArray, oldLength+1); 
+0

FYI - Array.Copy는 실제로 루프보다 느린 경우가 많습니다. 이 경우에는 int를 복사하기 때문에 모든 복사본에서 내부적으로 boxing/unboxing을 수행합니다. 이것이 장점 중 하나였습니다 .net2와 generics가 가져 왔습니다. –

3

불행하게도 당신이 정말로에 도움을받을 수 있습니다

있는 유일한 방법은 당신이 실제로이 일 가능성이있는 Array.copy

int oldLength = dataStruct.myStaticArray.Length; 
myObject[] newMyObjectArray = new myObject[oldLength + 1]; 
Array.copy(dataStruct.myStaticArray, newMyObjectArray, oldLength); 

dataStruct.myStaticArray[oldLength] = new myObject(); 
dataStruct.myStaticArray = newMyObjectArray; 

편집을 루프를 방지 할 수 있다는 것입니다 유형을 변경할 수 없습니다.

왜 안 되니? 유일한 합리적인 대답은 함수를 반환하거나 매개 변수로 요구하는 함수와 함께 사용해야하는 API를 가지고 있다는 것입니다. 이 경우 List<T>을 사용하고 필요에 따라 .ToArray() 또는 .AddRange()라고 부릅니다.

관련 문제