1

私は周りを見回してきましたが、これまでのところこれを行う良い方法を見つけることができませんでした. よくある問題ですね、きっと。

次のものがあるとします。

class SomeClass : IComparable
{ 
    private int myVal; 
    public int MyVal
    { 
        get { return myVal; } 
        set { myVal = value; }
    }

    public int CompareTo(object other) { /* implementation here */ }
}

class SortedCollection<T>
{
    private T[] data;
    public T Top { get { return data[0]; } }

    /* rest of implementation here */
}

バイナリ ヒープを実装し、Insert() および DeleteMin() 操作のみをサポートするのではなく、最高 (場合によっては最低) の優先度値での「ピーク」をサポートしたいという考えです。スタック上。ハイゼンベルクが好きだったことは一度もありませんでした。「物事を変えることなく物事を見ることはできません」という不確定性原理. ごみ!

明らかに問題は、呼び出しコードが Top プロパティを介して MyVal (SortedCollection を想定) を変更するのを防ぐ手段が提供されていないことです。この操作では、ヒープが間違った順序で配置される可能性が明確にあります。Top プロパティを介してヒープの内部要素に変更が適用されないようにする方法はありますか? それとも、「インスタンスが挿入されてからキューから取り出されるまでの間にインスタンスを変更しない場合にのみ安定します。YMMV」という警告付きのコードを使用するだけですか。

4

5 に答える 5

1

読み取り専用プロパティ (つまり、getter のみを持つプロパティ) を持つことができます。

private int myVal;
public int MyVal { get { return myVal; } }

ただし、注意してください。これは常に期待どおりに機能するとは限りません。検討:

private List<int> myVals;
public List<int> MyVals { get { return myVals; } }

この場合、クラスが使用する List を変更することはできませんが、その List の 、 などのメソッドを呼び出すことはでき.Add()ます.Remove()

于 2009-07-20T23:14:05.110 に答える
1

getプロパティは、 /に対して同じアクセシビリティを持っている必要はありませんsetこれは、値の型(通常は値の型structのみを含む s) または不変の参照型を返すものすべてに対応します。

public int MyVal
{ 
    get { return myVal; } 
    private set { myVal = value; }
}

変更可能な参照型の場合、 s を返すか、呼び出し元がそれらを変更できないようにするためにClone()使用するなど、他のオプションがあります。ReadOnlyCollection<T>

private List<int> data;

public IList<int> Data
{
    get { return new ReadOnlyCollection<int>(this.data); }
}
于 2009-07-20T23:18:06.770 に答える
1

あなたの質問に答えるには:いいえ、あなたが望むような振る舞いを実装する方法はありません - T が参照型である限り(そしておそらくいくつかの値型であっても)

あなたは本当にそれについて多くをすることはできません. ゲッターを提供する限り、呼び出しコードは、データのアクセス可能性 (つまり、プロパティ、フィールド、およびメソッド) に応じて、データの内部コンテンツを変更できます。

class SomeClass : IComparable
{ 
    private int myVal; 
    public int MyVal
    { 
        get { return myVal; } 
        set { myVal = value; }
    }

    public int CompareTo(object other) { /* implementation here */ }
}


class SortedCollection<T>
{
    private T[] data;
    public T Top { get { return data[0]; } }

    /* rest of implementation here */
}

//..
// calling code
SortedCollection<SomeClass> col;
col.Top.MyVal = 500;  // you can't really prevent this

私が言いたいのは、あなたがコントロールしていないクラスの場合、それを実際に防ぐことはできないということです。この例では、他の人が述べているように、MyVal のセットを非公開にするか省略することができます。ただし、SortedColleciton はジェネリック クラスであるため、他の人の構造については何もできません

于 2009-07-20T23:29:03.707 に答える
0

プロパティのゲッターのみを実装し、メソッドを追加/削除してコレクションを変更します

于 2009-07-20T23:17:04.217 に答える
0

私は今あなたの問題を理解しています。私はこれがうまくいくと思います:

class SortedCollection<T> where T: ICloneable
{
    private T[] data;
    public T Top 
    { 
         get 
         { 
             T ret = (T)data[0].Clone();
             return ret; 
         }
    }

    /* rest of implementation here */
}

ICloneable 制約は、型パラメーターが ICloneable インターフェイスを実装することを保証します。(これが許容される場合)

于 2009-07-21T01:38:37.863 に答える