2012-04-29 10 views
0

私はクラスCのfriendキーワードを使用するのと同じ方法で、クラスBの保護されたメンバーにアクセスする必要があるクラスAを1つ持っています。しかし、内部修飾子は私のニーズに合っていません。クラスBは、クラスAのインスタンスを作成し、そのプライベートデータを変更し、そのクラスへの参照を返す必要があります。これらのクラスAのメンバーは元の発信者にプライベートにする必要があります。別のクラスの保護されたメンバーへのアクセス

public class A 
{ 
    protected int x; 
} 

public class B 
{ 
    public static A CreateClassA() 
    { 
     A x = new A(); 
     x.x = 5; // ERROR : No privilege 
     return x; 
    } 
} 
+1

をしようとしましたか? –

答えて

2

protectedフィールドのパブリックセッターを作成するか、クラスから継承する必要があります。

public class A 
{ 
    protected int x; 

    public int X { set { x = value; } } 
} 

public static A CreateClassA() 
{ 
    A x = new A(); 
    x.X = 5; 
    return x; 
} 

または:

public class B : A 
{ 
    public static A CreateClassA() 
    { 
     this.x = 5; 
     return x; 
    } 
} 
+1

これはフィールドであり、プロパティではありません。セッターは適用されません。 –

+1

@MarcGravell - はい、私の間違いです。しかし、フィールドのためのパブリックセッターを追加することはOKでしょうか? – Oded

+0

私はそれを後にすることができます、確かに! –

0

あなたはあなたがどちらかできるようになりましたA.から継承されている場合は、保護されたメンバーのみにアクセスすることができます。publicメソッドSETXを作る

  • から

    • 継承(int型newX)の値を設定しますXの
  • +0

    それは私が考えていたものですが、発信者が利用できるパブリックなSet()メソッドを持つことは、本質的に読み取り専用のデータなので、クラスAの機能を混乱させる可能性があります。継承は私がそれを使用しているという観点からは意味をなさないでしょう。私はそれが唯一の選択肢ではないことを願っています。 – user1364556

    +0

    フィールドが不変に動作するようにするには、Aを引数として受け取るコンストラクタをクラスAに追加します。 – Chopin

    +0

    これは素晴らしいことです。このようにして、xはクラスAファミリーの外から1回しか設定できません。Aから継承したクラスは、Aのインスタンスが作成された後でも値を変更できることに注意してください。 –

    1

    この試してみてください:あなたは公式のMSDNフレンドアセンブリをチェックする必要があります

    public class A 
    { 
        public A() { } 
    
        public A(int x) 
        { 
         this.x = x; 
        } 
    
        protected int x; 
    } 
    
    public class B 
    { 
        public static A CreateClassA() 
        { 
         A x = new A(5); 
         return x; 
        } 
    } 
    
    +1

    作成されたすべてのクラスAに対してクラスBが存在しますか? – user1364556

    +0

    静的でない限りは使用できません。私が間違っているなら、私を訂正してください。私は複雑なオブジェクトを構築するために、この種のクラスを使用します。何かのようなもの。 SomeObject.Builder()。DoSomething()。 SomeObject = A、Builder = B、DoSomething = CreateClassA – mynkow

    +0

    'public class B'の部分だけを残したらどうなりますか?したがって、クラスAには「public static A CreateClassA()」が含まれています(本当に良い名前ではなく、ClassAのインスタンスを作成し、ClassA自体は作成しません)。私もそのトリックを行うだろうと思う –

    0

    他の代替を。あなたができることの例により、 http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx

    using System.Runtime.CompilerServices; 
    using System; 
    
    [assembly: InternalsVisibleTo("AssemblyB")] 
    public sealed class A 
    { 
        internal int x; 
    } 
    

    とアセンブリBセットからは/内部メソッド/フィールドを呼び出します。

    を考えてみましょう:

    A foo = new A(); 
    FieldInfo privateField = foo.GetType().GetField("x", BindingFlags.NonPublic | BindingFlags.Instance); 
    privateField.SetValue(foo, 5); 
    

    注意:上記のコードの使用

    2

    public class A 
        { 
         protected int x; 
    
         public class B 
         { 
          public static A CreateClassA() 
          { 
           A x = new A(); 
           x.x = 5; // ERROR : No privilege 
           return x; 
          } 
         } 
        } 
    
    2

    質問は講義や指振るずに、この時点では少し古いですが、ここであなたが求めるものをやって、もう一つの方法ですカプセル化を破り、背骨を曲げ、OOの純粋主義者の鋭い叫び声から耳の損傷を引き起こす可能性があります。

    ...しかし、それはC#の友人キーワードの欠如を補うために、ファクトリクラスに最適です。

    警告2:これは遅いです。

    3

    あなたは他のアセンブリで同じアセンブリ内のすべてのクラスにアクセスできるだけでなく、サブクラスを与える代わりにinternalprotected internalを使用することができます。その悪夢のうち、あなたの自己を再設計

    public class A 
    { 
        protected internal int x; 
    } 
    
    public class B 
    { 
        public static A CreateClassA() 
        { 
         A x = new A(); 
         x.x = 5; // hurray 
         return x; 
        } 
    } 
    
    関連する問題