2016-07-24 21 views
1

コンパイラエラー '変数ではないため式を変更できません'が表示されます。構造体のコピーが返されるので、structプロパティに値を代入することはできませんが、この場合は当てはまりません。構造体インデクサに値を代入する

私は2つの配列を同期させておくことを目的としたDualArrayクラスを持っています。 Aプロパティを使用して「最初の」配列の項目にアクセスし、Bのプロパティを使用して「2番目の」配列に項目をアクセスしたいとします。これらのプロパティは、それぞれの配列にインデクサを持つ構造体を返します。

public struct Accessor<T> 
{ 
    private readonly T[] _array; 
    public Accessor(T[] array) 
    { _array = array; } 
    public T this[int index] 
    { 
    get { return _array[index]; } 
    set { _array[index] = value; } 
    } 
} 
/// <summary> 
/// Maintains two arrays. 
/// </summary> 
public class DualArray<T1, T2> 
{ 
    // ... 
    public Accessor<T1> A 
    { 
    get { return new Accessor<T1>(_arrayT1); } 
    } 
    public Accessor<T2> B 
    { 
    get { return new Accessor<T2>(_arrayT2); } 
    } 
    // ... 
} 

私はこのコードを使用しようとする今、私はエラーを取得:

DualArray<int, bool> dual = new DualArray<int, bool>(); 
// ... 
dual.A[5] = 2; // <-- sad trombone. 

私はクラスに私のアクセサー・タイプを変更すると、それはすべて正常に動作しますが、確実に構造体がコピーされても関連する配列への参照はまだ有効ですか?あるいは、実際のエラーではなく、私がしてはいけないことをやっているので、この場合のエラーですか?

答えて

1

"I understand that one cannot assign a value to a struct property because a copy of a struct is returned, but I don't think that applies in this case."

確かに、この場合には、それが正常になり、バグが発生しないでしょう。
しかし、コンパイラはこれを許可しません。なぜなら、この構造体への書き込みはバグの原因となる可能性が高いからです。変数に格納し、そう

Cannot modify a value type return value of `DualArray.A'. Consider storing the value in a temporary variable.

エラーメッセージは、ソリューションが含まれてい

var a = dual.A; 
a[5] = 2; 
+0

ありがとう、私はそれがおそらくそれほど重大なものだからといって、おそらくエラーとして偽装している警告であると考えました。ソリューションを恥ずかしく思うと、名前の付いたアクセサーを持つことの正体が破壊されます。私はアクセサーを参照タイプに変更しました。これにより、簡潔な割り当てを保つことができます。 –

+1

@DavidRutten:「エラーになりすます」という警告ではありません。エラーです。表現「dual.A」は変数ではなく値として分類されます。したがって、インデクサ設定ツールを使用することはできません。 *これを許可したコンパイラは、言語仕様に違反しています。 –

+0

@JonSkeet、私はそれが実際には無意味ではなく、そのように定義されているので、エラーです。十分に公正な、私は仕様デザイナーが芽の中にそのような危険なコードを挟むことが重要だと感じた理由を理解する。 –

0

あなたはこれを行うことができます。

DualArray<int, bool> dual = new DualArray<int, bool>(); 
var acc = dual.A; 
acc[5] = 2; 

オリジナルデザインのエラーが予期しない結果を引き起こす可能性がありますプロパティを直接(メソッドから返された)値型の変更によるものであることがのコピーを指しますので、値の型。しかし、クラス内で構造体を構築しているバッキング配列を格納することで、参照型内で値型を混在させているので、予期しない結果が得られないため、エラーdocsから

This error occurs because value types are copied on assignment. When you retrieve a value type from a property or indexer, you are getting a copy of the object, not a reference to the object itself. The copy that is returned is not stored by the property or indexer because they are actually methods, not storage locations (variables). You must store the copy into a variable that you declare before you can modify it.

If you are defining the class or struct, you can resolve this error by modifying your property declaration to provide access to the members of a struct. If you are writing client code, you can resolve the error by creating your own instance of the struct, modifying its fields, and then assigning the entire struct back to the property. As a third alternative, you can change your struct to a class.

+0

でも変更するには、私の値の型には何もありません、バック配列に委任すべてそれラップ、配列は参照型です。 –

+0

編集に対する応答:どの時点でAに値を割り当てていますか? –

+0

@DavidRutten 'dual.A'は構造体のコピーを返します。 – user3185569

関連する問題