2016-03-03 4 views
4

Прежде всего позвольте мне начать с того, что я действительно понимаю спецификаторы доступа. Я просто не вижу смысла использовать их в классах. Имеет смысл методы, позволяющие ограничить их сферу применения, но на классах, почему вы хотите получить частный класс, не означает ли это, чтобы классы могли повторно использовать их?Общие сведения о спецификаторах доступа в классах на C#

Какова цель спецификаторов доступа при объявлении класса на C#? Когда вы их используете?

Благодаря

+0

Вы должны прочитать об пространствах имен. – dotctor

+2

Если вы хотите ограничить площадь вашего публичного API, это одна из причин. Подумайте об инкапсуляции, и что это значит ... Вы действительно хотите, чтобы ваши потребители видели внутренние детали реализации, если им никогда не нужно их трогать? Что относительно частных вложенных классов, которые используются в контексте одного класса ... Etc – Charleh

+1

У вас может быть большой класс и внутри 'private class'. Затем вы можете создать экземпляр его в окружающем классе, но не извне. Возможно, этот внутренний класс настолько специфичен, что его нельзя использовать повторно в другом месте. –

ответ

6

Ну, допустим, что вы хотите, класс будет доступен только внутри своей собственной сборки:

internal class Test 

Давайте предположим, что у вас есть два класса, один внутри другого (вложенных классов):

protected internal class TestA 
{ 
    private TestB _testB; 

    private class TestB 
    { 
    } 

    public TestA() 
    { 
     _testB = new TestB(); 
    } 
} 

Класс TestB может быть доступен только внутри методов/свойств/конструкторов внутри TestA или внутри себя.

То же самое относится к модификатору protected.

// Примечание

Если вы не указываете модификатор доступа, по умолчанию он будет private, так на моем примере следующая строка:

private TestB _testB; 

равно

TestB _testB; 

То же относится и к классу.

Специальные Модификатор

Тогда есть protected internal, которая соединяет оба модификатора, так что вы можете получить доступ только тот класс, внутри одной и той же сборки ИЛИ из класса, который является производным от этого одного, даже если он ISN» t в той же сборке.Пример:

Ассамблея 1:

public class TestA : TestB 
{ 
    public TestB GetBase() 
    { 
     return (TestB)this; 
    } 

    public int GetA1() 
    { 
     return this.a1; 
    } 
} 
protected internal class TestB 
{ 
    public int a1 = 0; 
} 

Программа

TestA _testA = new TestA(); // OK 
TestB _testB = new TestB(); // ERROR 

int debugA = new TestA().a1 // ERROR 
int debugB = new TestA().GetA1(); // OK 

TestB testB_ = new TestA().GetBase(); // ERROR 

Источник

Link (Access Modifiers)

Тип или элемент может быть доступен любым кодом в той же сборке, , но не из другого узла.

Тип или элемент может быть доступны только с помощью кода в том же классе или структуры.

Тип или элемент может быть доступны только с помощью кода в том же классе или структуры, или в классе, который является производным от этого класса.

Тип или элемент может быть доступна любой другой код в том же сборки или другую сборку, которая ссылается на нее.

+0

Если я это правильно понимаю, это больше для людей, создающих публичные API, если мое предположение верно, я мог бы оставить все мои классы без спецификаторов доступа для личных/локальных проектов, поскольку по умолчанию это 'internal', correct? –

+0

По умолчанию 'private', обычно люди просто используют' public', потому что это просто и не требует оценки кода. Но все дело в моделях, обслуживании, гибкости и безопасности. –

+1

Большое спасибо за разъяснение. –

3

Я дам вам пример внутреннего класса. Представьте, что у меня есть DLL. Создайте эту DLL Я хочу выставить только один класс под названием A. Однако этот класс A должен иметь доступ к другим классам внутри DLL - таким образом, я сделаю все остальные классы внутри внутренней библиотеки DLL. Следовательно, из DLL вы можете использовать только класс A, а A все равно могут обращаться к другим классам внутри DLL - вы, однако, не можете.

+0

Смысл, спасибо большое. –

3

Наибольшее преимущество использования спецификаторов доступа - это когда кто-то использует ваши классы. Четко указывая, что должно и что не следует затрагивать в ваших объектах, вы можете защитить свой внутренний механизм и целостность вашего объекта от неправильного использования или повреждения.

С большими классами, если вы сделали все общедоступным, вы также затрудняете работу с вашим кодом с IntelliSense, что очень удобно, когда вы имеете дело с неизвестными библиотеками.

+0

Большое спасибо за хорошую информацию. –

0

Я создал одно приложение для понимания спецификаторов доступа.

Это будет легче понять с помощью кода вместо Теории.

Я добавил свои примечания в код, для лучшего руководства.

namespace ConsoleApplication1 
{ 
    //A normal public class which contains all different types of access-modifier classes in the assembly named 'ConsoleApplication1' 
    public class Base 
    { 
     public class PublicBase 
     { 
      public static void fn_PublicBase() 
      { 
       Console.WriteLine("fn_PublicBase"); 
      } 
     } 
     private class PrivateBase 
     { 
      public static void fn_PrivateBase() 
      { 
       Console.WriteLine("fn_PrivateBase"); 
      } 
     } 

     protected class ProtectedBase 
     { 
      public static void fn_ProtectedBase() 
      { 
       Console.WriteLine("fn_ProtectedBase"); 
      } 
     } 

     internal class InternalBase 
     { 
      public static void fn_InternalBase() 
      { 
       Console.WriteLine("fn_InternalBase"); 
      } 
     } 

     protected internal class ProInternalBase 
     { 
      public static void fn_ProInternalBase() 
      { 
       Console.WriteLine("fn_ProInternalBase"); 
      } 
     }  

     //TIP 1:This class is inside the same class 'Base' so everything is accessible from above.Hurray!! 
     class Base_Inside 
     { 
      public static void fn_Base_Inside() 
      { 
       //All methods are easily accessible.Does not consider a modified indeed. 
       PublicBase.fn_PublicBase(); 
       PrivateBase.fn_PrivateBase(); 
       ProtectedBase.fn_ProtectedBase(); 
       InternalBase.fn_InternalBase(); 
       ProInternalBase.fn_ProInternalBase(); 
      } 
     } 
    } 

    //Different class but inside the same assembly named 'ConsoleApplication1' 
    public class Base_Sibling : Base 
    {   
     //TIP 2:This class is NOT in same class 'Base' but in the same assembly so only protected is NOT accessible rest all are accessible.   
     public void fn_Base_Sibling() 
     { 
      PublicBase.fn_PublicBase(); 
      //PrivateBase.fn_PrivateBase();  //ERROR:Accesibility of 'protected'    
      ProtectedBase.fn_ProtectedBase(); //protected is accessible because Base_Sibling inherit class 'Base'. you can not access it via Base.ProtectedBase 
      InternalBase.fn_InternalBase(); 
      ProInternalBase.fn_ProInternalBase(); 
     } 
    } 
} 

Теперь Понять разницу между внутренней, защищенной внутренней, я добавил один для проекта под названием с Assembly_1 в одном растворе.

Я унаследовал Базовый класс из ConsoleApplication1 к производный класс Assembly_1.

namespace Assembly_1 
{ 
    //TIP:if it does not inherit class 'ConsoleApplication1.Base' then we can not access any thing beacuse this is different assembly. 
    //TIP:only INTERNAL is NOT accessible , rest all are accessible from first assembly if it inherits class 'Soul' 
    public class Derived : ConsoleApplication1.Base 
    { 
     public class PublicDerived 
     { 
      public static void fn_PublicDerived() 
      { 
       PublicBase.fn_PublicBase();    //YES, becuase this is 'public' 
       //PrivateBase.fn_PrivateBase();   //No, becuase this is 'private' 
       ProtectedBase.fn_ProtectedBase();  //YES, becuase this is 'protected' 
       //InternalBase.fn_InternalBase();   //No, becuase this is 'internal' 
       ProInternalBase.fn_ProInternalBase(); //YES, becuase this is 'protected internal' 
      } 
     } 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^