2017-04-16 11 views
2

다음 두 코드를 모두 시도해 보았습니다. 둘 다 같은 방식으로 작동하는 것 같습니다. ref T 인덱서와 get/set 인덱서간에 차이가 있습니까?

// Case 1: ref T indexer 
class Map { 
    Tile[,] tiles; 

    public ref Tile this[int x, int y] 
     => ref tiles[x, y]; 
} 

// Case 2: get/set indexer 
class Map { 
    Tile[,] tiles; 

    public Tile this[int x, int y] { 
     get => tiles[x, y]; 
     set => tiles[x, y] = value; 
    } 
} 

tiles 생성자 초기화되었다고 가정하고, 그 Tilestruct이다. 둘 사이에 주목할만한 차이가 있습니까? Tileclass 인 경우 어떻게됩니까?

+0

유형이 변경 될 때만 차이가 있습니다 –

+0

네, 큰 차이가 있습니다. Tile에 X 속성을주고 map [0,0] .X = 42;를 시도하십시오. –

+0

아, 알겠습니다. 사례 2에서는 속성을 수정할 수 없습니다. 고마워, 나는 그 때 이전과 갈 것이다. :) – Dave

답변

2

타일이 생성자에서 초기화되고 해당 타일이 구조체라고 가정합니다. 둘 사이에 주목할만한 차이가 있습니까?

CASE 1

// Case 1: ref T indexer 
class Map { 
    Tile[,] tiles; 

    public ref Tile this[int x, int y] 
     => ref tiles[x, y]; 
} 

당신이 그것을 수정하고 심지어 다른 개체로 설정 할 수 있도록이 인덱스 Title 객체에 ref을 반환한다. 이것은 ref을 반환 할 수있는 C# 7.0의 새 기능입니다 (태그를 추가 한 후). 즉 값이 아닌 저장 위치를 ​​반환합니다.

저장 위치를 ​​반환하기 때문에 인덱싱 된 항목에 새로운 Tile 개체를 완전히 할당 할 수 있습니다. ref이 없으면 수정 만 할 수 있습니다.

CASE 2

다음
class Map { 
    Tile[,] tiles; 

    public Tile this[int x, int y] { 
     get => tiles[x, y]; 
     set => tiles[x, y] = value; 
    } 
} 

은 동일하지만입니다 C# 간결 7.0없이 : 당신이 사본을 얻을 것이다 당신에게 인덱스를 Tile 이후

class Case2MapWithoutCSharp7 
{ 
    Tile[,] tiles; 

    public Tile this[int x, int y] 
    { 
     get { return tiles[x, y]; } 
     set { tiles[x, y] = value; } 
    } 
} 

struct이며, 경우 당신은 이것을 시도합니다 (Tile은 속성이 X이라고 가정) :

map[0, 0].X = 10; 

오류 CS1612 변수가 아니기 때문에 'Case2MapWithoutCSharp7.this [int, int]'의 반환 값을 수정할 수 없습니다.

컴파일러는 여러분이 생각하는 (인덱싱 된 항목 수정하기) 것이 실제로 무엇을하고있는 것은 아니라는 것을 분명히 밝히기 위해 오류를 던지고 있습니다. 실제로 사본을 수정하고 있으므로 정확히 수행해야합니다. 그래서, X을 설정 할 수 있도록,이 같은 복사본을 수행해야합니다

var tile = map[0, 0]; 
tile.X = 10; 

당신은 그 오류 here에 대한 자세한 내용을보실 수 있습니다.

타일이 class 인 경우 어떻게됩니까?

첫 번째 경우에는 저장 위치를 ​​반환하기 때문에 인덱싱 된 항목에 새로운 Tile 개체를 완전히 할당 할 수 있습니다.

두 번째 경우는 ref이없고 class 개체가 참조로 전달되기 때문에 개체를 수정할 수는 있지만 완전히 새로운 개체에 대한 참조는 설정할 수 없습니다.

map[0, 0].X = 2; 

을하지만 당신이 한 경우 : : 그래서 당신은이 작업을 수행 할 수 있습니다

var tile = map[0, 0]; 
tile = new Tile(); 
tile.X = 5; 

을 당신은 분명히 새로운 Tile 아닌 하나는 인덱스를 돌연변이 있습니다.