タイルがコンストラクタで初期化され、そのタイルが構造体であると仮定します。両者に顕著な違いはありますか?
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なしです:
class Case2MapWithoutCSharp7
{
Tile[,] tiles;
public Tile this[int x, int y]
{
get { return tiles[x, y]; }
set { tiles[x, y] = value; }
}
}
あなた指数、それはあなたがコピーを取得している場合になるときTile
は、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
はなく、あなたがインデックス1を変異されています。
タイプが変更可能な場合のみ違いがあります –
はい、大きな違いがあります。 TileにXプロパティを与え、map [0,0] .X = 42;を試してください。 –
ありがとうございます。ケース2では、そのプロパティを変更することはできません。ありがとう、私は前者と行くつもりです。 :) – Dave