2012-04-29 4 views
0

나는 C 클래스에서 friend 키워드를 사용하는 것과 같은 방식으로 클래스 B의 보호 된 멤버에 액세스해야하는 클래스 A를 하나 가지고 있습니다. 그러나 내부 수정자는 내 필요에 맞지 않습니다. 클래스 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 - 네, 저의 실수입니다. 하지만 현장에 공공 세터를 추가하는 것이 좋습니다. 그렇지 않습니까? – Oded

+0

나는 그것을 뒤로 할 수있다. –

0

당신이 중 하나를 지금 할 수있는 A. 상속하는 경우는, 보호 된 멤버 만 액세스 할 수 있습니다 : public 메소드 setX을 확인

  • 에서

    • 상속 (INT이 newX) 값을 설정하는 of X
  • +0

    그게 내가 생각했던 것이지만, 호출자가 활용할 수있는 공용 Set() 메서드를 사용하면 본질적으로 읽기 전용 데이터이므로 클래스 A의 기능을 뒤엎을 수 있습니다. 상속은 내가 ​​사용하고있는 관점에서 이해가되지 않을 것이며, 유일한 선택이 아니기를 바랍니다. – user1364556

    +0

    해당 필드가 변경되지 않도록하려면 클래스 A에 인수를 인수로받는 생성자를 추가하십시오. – Chopin

    +0

    좋은 소식입니다. 이런 식으로 x는 Class A 가족 외부에서 한 번만 설정할 수 있습니다.A를 상속 한 클래스는 A의 인스턴스가 만들어진 후에도 여전히 값을 변경할 수 있습니다. –

    1

    이 시도 :

    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

    생성 된 모든 클래스 A에 대해 클래스 B가 존재합니까? – user1364556

    +0

    정적 일 때만 가능합니다. 내가 틀렸다면 나를 바로 잡아라. 복잡한 객체를 만드는 데이 종류의 클래스를 사용합니다. 뭔가. SomeObject.Builder() .Disomething(). SomeObject = A, Builder = B, DoSomething = CreateClassA – mynkow

    +0

    'public class B'부분을 그냥 남겨두면 어떨까요? 그래서 클래스 A는 'public static A CreateClassA()'를 포함합니다. 실제로는 좋은 이름이 아니며 ClassA 자체가 아니라 Class A의 인스턴스를 만듭니다. 너무 속임수를 쓰는 것 같아요 –

    0

    다른 대안 :

    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; 
        } 
    } 
    
    2

    을 당신은 공식 MSDN 친구 총회를 확인해야합니다./

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

    그리고에서 조립 B 세트를 내부 방법/필드를 호출하는 예에 의해 http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx 당신은 할 수 있습니다.

    이 고려 :

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

    경고 : 위의 코드를 사용

    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; 
        } 
    } 
    
    관련 문제