в c #, возможно ли получить доступ к общим защищенным полям одного дочернего элемента в другом дочернем классе?

#c# #protected

#c# #защищенный

Вопрос:

Смотрите Вопрос в коде:

 class commonParent {
     protected string name;
}

class child1:commonParent{
    // do some stuff
}

class child2:commonParent{
   // do some stuff

   protected void test(){
       child1 myChild1 = new child1();

       //is it possible to access myChild1.name in child2 without 
       //declaring the name public or internal?

      // I want to do something like this:
      string oldName = myChild1.name;

      //but I got the error:
      //Error   46  Cannot access protected member 'commonParent.name' 
      //via a qualifier of type 'child1'; the qualifier must be of 
      //type 'child2' (or derived from it)  
   }
}
  

Поле «name» используется только всеми дочерними элементами класса commonParent . Я хочу скрыть это поле извне (классы, не производные от commonParent), оставив его доступным в рамках commonParent и его дочерних элементов.

Комментарии:

1. Выдавало ли это какую-либо ошибку при попытке доступа myChild1.name ?

2. Да, я получил эту ошибку: ошибка 46 Не удается получить доступ к защищенному члену ‘commonParent.name ‘ через классификатор типа ‘child1’; классификатор должен быть типа ‘child2’ (или производным от него)

Ответ №1:

Прочитайте следующее сообщение в блоге Эрика Липперта,

попробуйте использовать protected internal , это сработает

Комментарии:

1. хорошая статья, хотя она не дает никакого ответа. кажется, что «защищенный внутренний» — это наименьшая видимость, которую я могу установить, чтобы добиться цели.

Ответ №2:

вы должны объявить его как минимум защищенным

Комментарии:

1. Я знаю — он спросил о внутреннем или общедоступном, поэтому я сказал ему, по крайней мере, защищен…..

Ответ №3:

Я думаю, что это плохой дизайн, вы должны объявить Name как Private и создать свойство с помощью Get,Set accessors , где вы можете выбрать, могут ли Get или Set быть общедоступными, частными или защищенными, в противном случае Protected позволит любым классам одного и того же пространства имен обращаться к полю или свойству.

Комментарии:

1. да, я знаю, что это правило. но в моей ситуации поле «name» используется только всеми дочерними элементами класса commonParent . Я хочу скрыть это поле извне, но оставить его доступным в рамках commonParent и его дочерних элементов.

Ответ №4:

Чтобы ответить на ваш вопрос, вы можете получить к ним доступ с помощью отражения. Однако это не то, на что вы хотите полагаться.

Ответ №5:

Мой подход к этому заключается в предоставлении защищенного статического метода, который имеет доступ к защищенному значению, но доступен только для производных классов, как в приведенном ниже коде:

 class commonParent
{
    protected string name;

    protected static string GetName(commonParent other)
    {
        return other.name;
    }
}

class child1 : commonParent
{
    // do some stuff
}

class child2 : commonParent
{
    protected void test()
    {
        child1 myChild1 = new child1();
        string oldName = commonParent.GetName(myChild1);

    }
}
  

Преимущество этого заключается в предоставлении доступа к защищенным данным только производным классам.