0

基本的に 3 つのプロパティのペアである 6 つのプロパティを持つクラスがあり、各ペアには 1 つのことに関するデータが含まれていました。これらのプロパティはすべて公開されていましたが、設定は保護されていました。以下のコードに示します。

public class MyClass
{
    public Data1Type Item1Data1 { get; protected set; }
    public Data2Type Item1Data2 { get; protected set; }
    public Data1Type Item2Data1 { get; protected set; }
    public Data2Type Item2Data2 { get; protected set; }
    public Data1Type Item3Data1 { get; protected set; }
    public Data2Type Item3Data2 { get; protected set; }
}

プロパティの各ペアは基本的に 1 つの項目として扱われるため、次のような構造体を作成することにしました。

struct Item
{
    Data1Type Data1;
    Data2Type Data2;
}

そこで、プロパティの各ペアを 1 つの構造体に置き換えましItemた。

私が今直面している問題は、3 組のプロパティで、以前と同じ保護レベルを持つ方法が見つからないことです。MyClass外部のすべてが構造体内のプロパティを取得できるようにしたいのですが、構造体内のプロパティを変更できるのは、構造体から派生したクラスItemだけです。MyClassItem

どうすればそのようなことができますか?それは可能ですか?

4

4 に答える 4

3

構造体を読み取り専用にして、値の制御を維持することができます。これは、.NETの一部で使用されるパターンです。

struct MyStruct
{
    public readonly int Field1;
    public readonly int Field2;

    public MyStruct(int i, int j)
    {
        Field1 = i;
        Field2 = j;
    }
}

次に、プロパティセッターを経由しない限り、構造体内の値が変更されないことを知って、以前と同じ方法でプロパティを作成できます。

于 2013-02-01T15:55:02.530 に答える
2

protected setter を使用して構造体型のプロパティを作成するだけです。

public class MyClass
{
    public Item Item1 { get; protected set; }
    public Item Item2 { get; protected set; }
    public Item Item3 { get; protected set; }
}

Struct は値型であるため、クライアントはアイテムのプロパティを MyClass から変更しData1たり、プロパティを変更したりできません (クライアントはアイテムのコピーを持ちます)。Data2また、保護されたセッターを使用すると、MyClass とその継承者のみが項目の新しい値を設定できます。あるアイテムのアイテム データを更新する場合は、class代わりに を使用しstructます。

于 2013-02-01T15:51:21.247 に答える
0

あなたはおそらくもっと読むべきです- それはimmutableであることをstruct意図しています。ItemMyClass

Stan Petrovs answerを見ると、構造体の作成方法がわかります。

次にMyClass、次のようなものが必要です。

protected void SetItem1Data1(DataType1 newValue) 
{
    this.Item1 = new Item(newValue, this.Item1.Data2);
}
于 2013-02-01T15:59:02.800 に答える
0

次のような構造には 2 つの方法しかありません。

someThing.someMember.nestedMember = someValue;

正当である可能性があります:someMemberクラスインスタンスへの参照を返すかsomeThing、参照が返されるとすぐに の関与が停止するか、そうでsomeThing.someMemberなければ class のフィールドでなければなりませんsomeThing。C#someMemberでは、構造体が返されたとしても、次のsomeMemberような可能性を考慮して合法でした。

public class Thing { ...
    private nestedType member_nestedMember;
    public struct MemberProxy {
        Thing _owner;
        internal MemberProxy(Thing owner) {_owner = owner;}
        nestedType nestedMember {
            get {return _owner.member_nestedMember;}
            set {_owner.member_nestedMember = value; }
        }
    }
    public MemberProxy someMember {get {return new MemberProxy(this);} }
}

このシナリオでは、MemberProxyは のデータを実際には保持していませんがnestedMember、その代わりに、データが含まれている実際の場所への参照を保持しています。したがって、 のインスタンスが書き込み可能でない場合でも、そのプロパティMemberProxyを設定しようとすると機能します。nestedMember残念ながら、読み取り専用の構造体値でプロパティ セッターを呼び出すことが役立つ場合がいくつかありますが (ArraySegment別のそのような例を提供します)、コンパイラにそのようなことを行うべきか、または行うべきかを伝える属性はまだ定義されていません。許されません。

現在のシナリオに戻ると、型または派生型が両方を変更せずにアイテムの一部を変更したい可能性がかなりある場合は、コンポジットのオープンフィールド構造を宣言することをお勧めします-項目タイプとそのタイプのクラスprotectedフィールド内のインクルード、およびそれらを返すパブリック プロパティ。そうすることで、派生クラスは次のように言うことができます:

item1.Data1 = whatever;

外部コードはItem1プロパティを使用する必要Data1がありますが、タイプの書き込み可能なフィールドが公開されている場合でもItem、次のように試みます:

item1.Data1 = whatever;

[読み取り/書き込みプロパティである場合にそのようなステートメントを受け入れる古いコンパイラでさえData1、それが有用である可能性があるという理論に基づいてData1、フィールドである場合は正しく拒否することに注意してください]。public の変更可能な構造を公開しないことに決めた場合は、いつでも次のようにすることができます。

public struct Item
{
   privateItem Value;
   public Type1 Data1 {get {return Value.Data1; }}
   public Type1 Data2 {get {return Value.Data2; }}
   Item(privateItem src)
   {
     Value = src;
   }
 }

個人的には、ラッピングのレイヤーを追加することに何の価値もないと思いますが、「公開された変更可能な構造体は悪である」という群衆をなだめるのに役立つかもしれません。

于 2013-02-02T17:29:51.390 に答える