Error CS1612: 変数ではないため、xxx の戻り値を変更できません
渡されたコピーを変更しようとした場合にエラーが出ます
エラー発生の理由がよくわからないケースになります
対処の方法についても考えていきましょう
C#でテスト
エラーになるコード
一見問題なく動作しそうですがダメですね
Square square = new Square();
square.Size.Height = 10.2f;
class Square
{
public Size Size { get; set; }
}
struct Size
{
public float Width;
public float Height;
}
発生するエラー
展開した様子
エラーの箇所はコメントアウトして展開しています
プロパティに着目してください
getのブロック内に記述されているコードは、メソッドになると考えてください
つまりreturn される値は、structの場合、コピーされた値が返されることになります
なので、この値を変更しても元の値に影響があるわけではありません
プログラマーは代入したい意思がありますが、ダメですよね
[CompilerGenerated]
internal class Program
{
private static void <Main>$(string[] args)
{
new Square();
}
}
internal class Square
{
[CompilerGenerated]
private Size <Size>k__BackingField;
public Size Size
{
[CompilerGenerated]
get
{
return <Size>k__BackingField;
}
[CompilerGenerated]
set
{
<Size>k__BackingField = value;
}
}
}
internal struct Size
{
public float Width;
public float Height;
}
対処
構造体をローカル変数に割り当てて、変数を「変更します
その後、代入することで対応します
Square square = new Square();
Size squareSize = square.Size;
squareSize.Height = 10.2f;
square.Size = squareSize;
class Square
{
public Size Size { get; set; }
}
struct Size
{
public float Width;
public float Height;
}
展開した様子
[CompilerGenerated]
internal class Program
{
private static void <Main>$(string[] args)
{
Square square = new Square();
Size size = square.Size;
size.Height = 10.2f;
square.Size = size;
}
}
internal class Square
{
[CompilerGenerated]
private Size <Size>k__BackingField;
public Size Size
{
[CompilerGenerated]
get
{
return <Size>k__BackingField;
}
[CompilerGenerated]
set
{
<Size>k__BackingField = value;
}
}
}
internal struct Size
{
public float Width;
public float Height;
}
Unityでのサンプル
エラーになるコード
Unityのコードでも上記と同じことが言えます
次の簡略化したコードを確認してください
実際のコードはx, y, zを構造体Vecter3で宣言されていますが、ここでは学習のため省略しています
GameObject player = new GameObject();
player.transform.Position.x = 1.2f;
class GameObject
{
public Transform transform = new Transform();
}
class Transform
{
internal Position Position { get; set; }
}
struct Position
{
public float x;
public float y;
public float z;
}
エラーになりますね
対処
一時変数を作成して、現在の値をコピーしておきます
xの値を更新します
更新した値を再度代入すればOKです
GameObject player = new GameObject();
Position tempPos = player.transform.Position;
tempPos.x = 1.2f;
player.transform.Position = tempPos;
class GameObject
{
public Transform transform = new Transform();
}
class Transform
{
internal Position Position { get; set; }
}
struct Position
{
public float x;
public float y;
public float z;
}
まとめ
構造体を使い、プロパティ経由でアクセスした場合、このようにエラーになります
特にUnityでコードを書いている人は一度は出会うエラーではないでしょうか
構造体ではなく、クラスだと参照値が渡されるので問題がないのですが、Transformクラスは、UnityEngine内部に宣言されたコードなのでプログラマーが対処できないですね
理屈を理解するのは難しいでしょうが、学習のため一度は確認しておきましょう
ディスカッション
コメント一覧
まだ、コメントがありません