int []가 참조 유형입니까 아니면 값 유형입니까?


124

int가 값 유형이라는 것을 알고 있지만 값 유형의 배열은 무엇입니까? 참조 유형? 가치 유형? 뭔가를 확인하기 위해 배열을 함수에 전달하고 싶습니다. 배열의 참조를 전달하기 때문에 배열을 전달해야합니까, 아니면 참조로 전달해야합니까?


11
앞으로는 변수를 만들고 해당 변수를 변경하는 메서드에 해당 변수를 전달하고 메서드를 실행 한 후 해당 변수의 값이 무엇인지 확인하여 참조 또는 값으로 무언가가 전달되는지 확인할 수 있습니다. 동일하면 값으로 전달되고, 참조로 전달됩니다.

11
@ darkassassin93 : 참조 또는 값으로 전달하는 것은 무언가가 참조 유형인지 값 유형인지와 관련이 없습니다. (값 유형은 참조로 전달 될 수 있고 참조 유형은 값으로 전달 될 수 있습니다.)
LukeH

2
대부분의 경우 필드 또는 변수 내에 [null]을 저장할 수 있다면 이것이 ref 유형이라고 가정 할 수 있습니다. 예외는 확실히 nullable 형식 (Nullable <int> 또는 int?)과 문자열입니다.
Noel Widmer

3
@ NoëlWidmer Strings는 예외가 아닙니다 : ref 유형입니다.
Arthur Castro

2
@ArthurCastro Argree to 50 % : 문자열은 참조 유형임을 의미하는 클래스에서 상속됩니다. 그러나 동등성은 참조가 아닌 ID (값 비교)를 기반으로하며 해당 전달 동작은 값 유형의 동작과 일치하도록 재정의됩니다. 기본적으로 정의에 따라 참조 유형이지만 구현에 따라 값 유형과 더 비슷하게 작동합니다.
Noel Widmer

답변:


201

배열은 여러 항목을 단일 컬렉션으로 처리 할 수있는 메커니즘입니다. Microsoft® .NET 공용 언어 런타임 (CLR)은 1 차원 배열, 다차원 배열 및 가변 배열 (배열 배열)을 지원합니다. 모든 배열 형식은 System.Object에서 파생 된 System.Array에서 암시 적으로 파생됩니다. 즉, 모든 배열은 항상 관리되는 힙에 할당되는 참조 유형 이며 앱의 변수에는 배열 자체가 아니라 배열에 대한 참조가 포함됩니다.

https://msdn.microsoft.com/en-us/library/bb985948.aspx


54
값 형식은 System.Object에서 상속되는 System.ValueType에서 상속됩니다. 따라서 Array가 System.Object에서 파생되었다고해서 참조 유형이라는 의미는 아닙니다. System.Array를 참조 형식으로 만드는 것은 인스턴스가 참조로 복사된다는 것입니다. IOW, System.Array가 클래스라는 사실에 집중하십시오. 그것이 그것을 참조 유형으로 만드는 것입니다.
P.Brian.Mackey 2013

8
<nitpick> 문서가 System.Object에서 파생 된 System.Array가 참조 형식으로 만든다는 것을 암시하는 것처럼 보일 수 있다는 것을 알고 있습니다. System.Object에서 파생 된 모든 유형이 참조 유형이라는 것이 사실이 아닐 수도 있지만이 규칙에 대한 유일한 예외는 컴파일러에서 다르게 처리되는 System.ValueType입니다. </ nitpick>
Yannick Motton

위의 링크가 끊어졌습니다. 다음은 System.Array의 상속 계층 구조를 보여주는 또 다른 msdn 링크입니다. msdn.microsoft.com/de-de/library/system.array(v=vs.110).aspx
MUG4N

System.Object에서 파생되는 모든 항목은 System.ValueType에서도 파생되지 않는 한 참조 형식입니다. @ P.Brian.Mackey 유형이 클래스라고해서 참조 유형이라는 의미는 아닙니다. 왜냐하면 배후에서 구조체는 System.ValueType에서 파생 된 클래스 일 뿐이 기 때문입니다.
David Klempfner

31

참조 유형 대 값 유형에 대한 가장 간단한 테스트는 참조 유형은 일 수 null있지만 값 유형은 할 수 없다는 것입니다.


46
... nullable 값 형식 (null 참조가 아닌 형식의 null 값을 의미하는 null로 값을 설정할 수 있음 )이고 여전히 값 형식 인 nullable 값 형식은 제외 됩니다.
Jon Skeet

1
가치 유형인지 아닌지 이해하려고 할 때 그렇게 생각하지 않았습니다! 좋은 생각입니다.
삼켜 진 elysium 2010 년


6

먼저 Array가 참조 유형이라는 것을 말씀 드리고 싶습니다. 왜? 여기에 한 가지 예를 던져 설명하겠습니다.

예:

int val = 0; // this is a value type ok
int[] val1 = new int[20] // this is a reference type because space required to store 20 integer value that make array allocated on the heap.

또한 참조 유형은 null 일 수 있지만 값 유형은 할 수 없습니다.

스택에 저장된 값 유형과 힙에 저장된 참조 유형

out 또는 ref를 사용하여 배열을 함수에 전달할 수 있습니다. 초기화 방법 만 다릅니다.

더..


3

참조 또는 값 유형인지 테스트하여 확인합니다.

// we create a simple array of int
var a1 = new int[]{1,2,3};
// copy the array a1 to a2
var a2 = a1;
// modify the first element of a1
a1[0]=2;
// output the first element of a1 and a2
Console.WriteLine("a1:"+a1[0]); // 2
Console.WriteLine("a2:"+a2[0]); // 2
//**************************
// all the two variable point to the same array
// it's reference type!
//**************************

온라인으로 테스트 할 수 있습니다 : https://dotnetfiddle.net/UWFP45


2
배열을 만들고 null에 할당하는 것이 더 쉬웠을 것입니다. 값 유형이면 컴파일이 실패합니다 ..
devoured elysium

미리주의하십시오. C # 8이 릴리스되면 nullable이 아닌 참조 형식이 null을 허용 할 수 없기 때문에 nullable 참조 형식 기능을 사용하는 경우에도 실패합니다.
Mark A. Donohoe

2

배열 자체는 참조 유형입니다. 해당 배열의 값은 배열 데이터 유형에 따라 결정되는 값 또는 참조 유형입니다. 귀하의 예에서 배열은 참조 유형이고 값은 값 유형입니다.

모든 단일 차원 배열은 암시 적으로 구현하는 IList<T>경우, <T>배열의 데이터 형식입니다. 대신 해당 인터페이스를 메소드 매개 변수의 데이터 유형으로 사용할 수 있습니다. IEnumerable<T>데이터 유형 에도 사용할 수 있습니다 . 두 경우 모두 (또는을 사용하더라도 int[]) 명시 적으로 ref매개 변수 로 전달할 필요가 없습니다 .


0

// 배열에 대한 참조는 값으로 전달됩니다. 이것이 혼란의 원인입니다 :-) ...

        int[] test = { 1, 2, 3, 4 };

        modifContenuSansRef(test);
        Console.WriteLine(test[0]); // OK --> 99 le contenu du tableau est modifié

        modifTailleSansRef(test);
        Console.WriteLine(test.Length); // KO --> 4 La taille n'est pas modifiée

    }

    static void modifContenuSansRef(int[] t)
    {
        t[0] = 99;
    }

    static void modifTailleSansRef(int[] t)
    {
        Array.Resize(ref t, 8);
    }

0

배열은 항상 참조 유형입니다. 배열에 int와 같은 값 유형 또는 문자열과 같은 참조 유형이 포함되는 것은 중요하지 않습니다.

int[] integers=new int[10];

정수 변수 자체에는 힙에 상주 할 배열에 대한 참조 만 포함됩니다.

또한 많은 사람들이 변수가 null인지 아닌지에 따라 참조 유형과 값 유형을 다를 수 있다고 언급합니다. C #에서 현재 값 유형도 null이 될 수 있음을 언급하고 싶습니다.

예를 들어

int? integer=null

유형이 참조인지 또는 값이 사실 변수에만 의존하는지 확인하는 좋은 방법이 아닙니다.


-2

약간의 통찰력 :

예를 들어, int단일 정수를 int[]나타내고 정수 배열을 나타냅니다.

특정 차원으로 배열을 초기화하려면 new키워드를 사용 하여 유형 이름 뒤의 대괄호 안에 크기를 제공 할 수 있습니다 .

//create a new array of 32 ints.
int[] integers = new int[32];

모든 배열은 참조 유형이며 참조 의미 체계를 따릅니다. 따라서이 코드에서 개별 요소는 기본 값 유형이지만 integers배열은 참조 유형입니다. 따라서 나중에 작성하면 :

int[] copy = integers;

이것은 단순히 동일한 배열을 참조하기 위해 전체 변수 사본을 할당하고 새 배열을 생성하지 않습니다.

C #의 배열 구문은 유연하므로 나중에 프로그램에서 배열의 크기를 동적으로 조정할 수 있도록 초기화하지 않고도 배열을 선언 할 수 있습니다. 이 기술을 사용하면 기본적으로 null 참조를 만들고 나중에 new키워드로 요청 된 동적 할당 메모리 위치에서 해당 참조를 가리 킵니다 .

int[] integers;
integers = new int[32];

감사합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.