Nice programing

foreach ()는 참조로 반복합니까?

nicepro 2020. 11. 20. 09:35
반응형

foreach ()는 참조로 반복합니까?


이걸 고려하세요:

List<MyClass> obj_list = get_the_list();
foreach( MyClass obj in obj_list )
{
    obj.property = 42;
}

obj나는 속성을 변경할 때 어딘가를 구축하면 변화가 개체의 인스턴스에서 유지되도록 목록에서 해당 객체에 대한 참조는?


예, obj컬렉션의 현재 개체에 대한 참조입니다 ( MyClass사실 클래스 라고 가정 ). 참조를 통해 속성을 변경하면 예상대로 객체를 변경하는 것입니다.

그러나 obj반복 변수이기 때문에 변수 자체를 변경할 수 없습니다 . 시도하면 컴파일 오류가 발생합니다. 즉, null을 사용할 수 없으며 값 유형을 반복하는 경우 값이 변경되므로 멤버를 수정할 수 없습니다.

C # 언어 사양 상태 (8.8.4)

"반복 변수는 포함 된 문 위로 확장되는 범위가있는 읽기 전용 지역 변수에 해당합니다."


예, 제네릭 유형을 List에서 IEnumerable로 변경할 때까지 ..


여기에 두 가지 다른 질문을하셨습니다. 순서대로 살펴 보겠습니다.

foreach 루프가 참조로 반복됩니까?

참조에 의한 C ++ for 루프와 동일한 의미에서 의미하는 경우 아니오. C #에는 C ++와 동일한 의미의 지역 변수 참조가 없으므로 이러한 유형의 반복을 지원하지 않습니다.

변화가 지속될 것인가

MyClass가 참조 유형이라고 가정하면 대답은 예입니다. 클래스는 .Net의 참조 유형이므로 반복 변수는 복사본이 아니라 하나의 변수에 대한 참조입니다. 이것은 값 유형의 경우에는 해당되지 않습니다.


글쎄, var 컬렉션을 반복 할 때 foreach 루프에서 변경 사항이 업데이트되지 않았습니다.

var players = this.GetAllPlayers();
foreach (Player player in players)
{
    player.Position = 1;
}

var를 List로 변경하면 작동하기 시작했습니다.


이 인스턴스에서 (를 사용하여 List<T>) 할 수 있지만 제네릭 IEnumerable<T>반복하는 경우 구현에 종속됩니다.

그것은 여전히 경우 List<T>또는 T[]예를 들어, 모두 예상대로 작동합니다. IEnumerable<T>yield를 사용하여 구성된으로 작업 할 때 큰 문제가 발생합니다 . 이 경우 더 이상 T반복 내의 속성을 수정할 수 없으며 동일한 속성을 IEnumerable<T>다시 반복 할 경우 표시 될 것으로 기대할 수 있습니다 .


이것은 구조체가 아닌 한 사실입니다.


C # 7.3 버전에서는 열거 자의 Current 속성이 참조 유형을 반환하는 경우 참조로 값을 변경할 수 있다는 점이 흥미로울 수 있습니다 . 다음이 유효합니다 (MS 문서의 Verbatim 사본).

Span<int> storage = stackalloc int[10];
int num = 0;
foreach (ref int item in storage)
{
    item = num++;
}

이 새로운 기능에 대한 자세한 내용은 C # foreach 문 | Microsoft 문서 .


음, "참조로 반복"이 의미하는 바를 정확히 이해하지 못한 채로 예 또는 아니오로 구체적으로 대답 할 수는 없지만 표면 아래에서 진행되는 작업은 .net 프레임 워크가 다음에 대한 "열거 자"클래스를 구성하고 있다는 것입니다. 클라이언트 코드가 foreach의 수명 동안 반복되는 컬렉션에 대한 참조 포인터를 유지하는 foreach를 호출 할 때마다 foreach가 반복 될 때마다 하나의 항목을 "전달"하고 포인터 또는 참조를 "증가"합니다. 다음 항목에 대한 열거 자 ...

이는 반복하는 컬렉션의 항목이 값 유형인지 참조 유형인지에 관계없이 발생합니다.


obj는 List 안의 항목에 대한 참조이므로 값을 변경하면 지속됩니다. 이제 걱정해야 할 것은 get_the_list (); List의 전체 복사본을 만들거나 동일한 인스턴스를 반환합니다.


예, 그렇기 때문에 foreach 문의 컨텍스트에서 열거 가능한 개체를 변경할 수 없습니다.

참고 URL : https://stackoverflow.com/questions/1538301/does-foreach-iterate-by-reference

반응형