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