2

プロパティを介して任意の内部クラスからメンバーにアクセスできるが、特定の内部クラスによってのみ設定できる構造体を定義するにはどうすればよいですか?(もし可能ならば。)

それが不可能な場合、同様の要件を達成するための回避策はありますか?

編集1:以下

理由:

_xと_arrBの2つのメンバーを持つクラスAがあります。_xは、xを介して内部クラス(クラスAを除く)によって読み取ることはできますが、変更することはできません。

また、内部クラスが_arrBのstructB要素を読み取り、それらのstructBのメンバーを読み取ることができるようにします。しかし、私はクラスAが_arrBのstructB要素またはそれらのstructBのメンバーのいずれかを変更できるようにしたいだけです。したがって、どの内部クラスがそのメンバーを変更できるかを指定できる構造体が必要だと思います。[1]

class A 
{
    private int _x;
    internal int x
    {
        private set
        {
            _x = value / 2;
        }
        internal get
        {
            return _x * 2;
        }
    }

    private B[] _arrB;
    internal B[] arrB
    { 
        private set
        {
            _arrB = value;
        }
        internal get
        {
            return _arrB;
        }
    }

    public A() 
    {
        _x = //value read from somewhere;            

        //do something to determine size
        _arrB = new B[size];
        //populate _arrB
        ...
    }


}

注:内部クラスとは、ネストされたクラスではなく、同じアセンブリ内のクラスを意味します。

[1]ただし、_arrBは配列であり、オブジェクトであり、参照型です。内部クラスが_arrBの参照を取得すると、structBの要素が制御なしで変更される可能性があります。内部クラスで_arr[0]をnullに設定したくないことに気づきました。したがって、どのソリューションでもこれを考慮に入れる必要があります。

その日の残りの時間について考え、考えたときに解決策を投稿します。

4

3 に答える 3

1

私が考えることができるのは、スタックトレースを使用して呼び出しフレームを取得し、次に呼び出しメソッドを取得し、次にそのメソッドの反映されたタイプを取得することだけです。次に、そのタイプが期待しているものであることを確認できます。

編集、警告、悪いコード:

StackTrace oStack = new StackTrace(true);

string callingType = oStack.GetFrame(1).GetMethod().ReflectedType.FullName;

if(callingType != "MyAcceptableClass")
    throw new MethodAccessException(
          callingType + " is not allowed to call this method");

私は個人的にあなたのデザインを再考します、多分これらのクラスは同じアセンブリにあるべきではありませんか?次に、2つのアセンブリをフレンドアセンブリにして、互いの内部メンバーにアクセスできるようにします。

于 2010-07-22T08:10:53.217 に答える
1

どうしてそんなことをしたいのかしら。醜いハックだけが可能です。

警告の開始:醜いコードが嫌いな場合は読まないでください!!!

デビッドニールが言ったこと。

それらを別々のアセンブリに入れて、フレンドリに設定することができます。

[assembly:InternalsVisibleToAttribute("assembly name", "key")]

次のようにクラスを設計できます。

internal struct ModifiedStruct
{
    public int Value {get; private set; }

    internal class ModifyingClass
    {
        public void ModifyValue()
        {
            ModifiedStruct s = new ModifiedStruct();
            s.Value = 456;
        }
    }

}

警告終了

編集(質問の変更)コレクションの変更を禁止するには、ReadOnlyCollectionクラスを使用します。

internal ReadOnlyCollection<B> BCollection
{
    get
    {
        return new ReadOnlyCollection<B>(_arrB);
    }
}
于 2010-07-22T08:21:14.483 に答える
0

フィールドに特定の値を使用して構造体を作成できる場合は、その構造体タイプの変更可能な格納場所を変更して、それらの値を使用してインスタンスを作成し、そのインスタンスを問題の格納場所にコピーすることで、これらの値を保持できます。言うことは、構造体タイプのパブリックとプライベートを問わず、すべてのフィールドでstruct1=struct2言うことなどと同じです。struct1.field1 = struct2.field1; struct1.field2 = struct2.field2;

于 2012-02-23T01:32:50.927 に答える