0

*解決済み。説明してくれてありがとう、この状況で値型を使用することの意味を完全には理解していませんでした。

静的クラスから使用している構造体があります。ただし、実行時に内部状態を出力すると、動作が予期しない動作を示しています。ここに私の構造体があります:

    public struct VersionedObject
    {

        public VersionedObject(object o)
        {
            m_SelectedVer = 0;
            ObjectVersions = new List<object>();
            ObjectVersions.Add(o);
        }

        private int m_SelectedVer;
        public int SelectedVersion
        {
            get
            {
                return m_SelectedVer;
            }

        }

        public List<object> ObjectVersions;//Clarifying:  This is only used to retrieve values,  nothing is .Added from outside this struct in my code.

        public void AddObject(object m)
        {
            ObjectVersions.Add(m);
            m_SelectedVer = ObjectVersions.Count - 1;
        }
    }

テストコード

        VersionedObject vo = new VersionedObject(1);
        vo.AddObject(2);//This is the second call to AddObject()
        //Expected value of vo.SelectedVerion:  1
        //Actual value of vo.SelectedVersion:   1

ここで、このコードを単独でテストする、つまりプロジェクトにコピーして試してみると、期待どおりの結果が返されます。

問題; 私の製品コードで観察しているのは、次のデバッグ出力です。

objectName, ObjectVersions.Count:2, SelectedVer:0,

なんで?私の理解とテストから、これはどのような状況でも完全に不可能なはずです。

私のランダムな推測では、ある種の不変性が起こっており、何らかの理由で新しい構造体がデフォルトのコンストラクターを介してインスタンス化されており、ObjectVersions データがコピーされていますが、m_SelectedVersion はプライベートであり、新しい構造体にコピーすることはできません。 ?
構造体を操作するための静的クラスとメソッドの使用は、それと関係がありますか?

私はとても困惑しており、現時点では勝手な推測をしているだけです。

4

2 に答える 2

1

構造体は値型です。したがって、実際のコードでオブジェクトの複数のコピーを作成している可能性があります。

構造体のコンテンツは値型にあまり適合しないため、構造体をクラスに変更することを検討してください(可変であり、可変の参照型も含まれているため)。

「構造体は値型」の詳細:

まず、すでに多くの良い答えがあるFAQを確認してください。

値の型は値によって渡されるため、関数を呼び出してそのようなオブジェクトを更新しても、元のオブジェクトは更新されません。SomeFunction(42)関数に整数値を渡すのと同じように扱うことができます。つまり、42の値を変更できると期待しますか?

struct MyStruct { public int V;}
void UpdateStruct(MyStruct x)
{
  x.V = 42; // updates copy of passed in object, changes will not be visible outside.
}
....
var local = new MyStruct{V = 13}
UpdateStruct(local); // Hope to get local.V == 42
if (local.V == 13) {
  // Expected. copy inside UpdateStruct updated,
  // but this "local" is untouched.
}
于 2012-08-07T00:21:55.993 に答える
1

なぜこれはクラスではなく構造体なのですか? List<T>さらに良いことに、バッキング ストア ( ) のサイズを追跡するのではなく、追跡するのはなぜList<T>ですか。その基になるバッキング ストアは公開されているため、構造体の知識がなくても操作できます。本番コードの何かが、構造体を経由せずにバッキング ストアに追加されていると思われます。

私だったら、クラスにしますが、次のように設定します...しかし、それはほぼ確実に重大な変更です。

public struct VersionedObject
{

    public VersionedObject()
    {
        this.ObjectVersions = new List<object>() ;
        return ;
    }

    public VersionedObject(object o) : this()
    {
        ObjectVersions.Add(o);
        return ;
    }
    public VersionedObject( params object[] o ) : this()
    {
        ObjectVersions.AddRange( o ) ;
        return ;
    }

    public int SelectedVersion
    {
        get
        {
            int value = this.ObjectVersions.Count - 1 ;
            return value ;
        }
    }
    public List<object> ObjectVersions  ;

    public void AddObject(object m)
    {
        ObjectVersions.Add(m);
        return ;
    }

}

これは構造体と同じセマンティクスを持つことに注意してください。ただし、SelectedVersionプロパティはバッキング ストアに実際にあるものを反映するようになりました。

于 2012-08-07T00:39:16.607 に答える