提问



我一直在使用public的所有大学时期,并且想知道publicprivateprotected之间的区别?


static做什么而不是什么都没有?

最佳参考


访问修饰符




  公开

  
  

    类型或成员可以由同一程序集中的任何其他代码或引用它的另一个程序集访问。

  

  
  的私有

  
  

    类型或成员只能由同一类或结构中的代码访问。

  

  
  的保护

  
  

    类型或成员只能由同一类或结构中的代码或派生类访问。

  

  
  的内部

  
  

    类型或成员可以由同一程序集中的任何代码访问,但不能从另一个程序集访问。

  

  
  受保护的内部

  
  

    类型或成员可以由同一程序集中的任何代码访问,也可以由另一个程序集中的任何派生类访问。

  



设置无访问修饰符时,将使用默认访问修饰符。因此,即使没有设置,也总会有某种形式的访问修饰符。


静态



  类上的static修饰符意味着该类无法实例化,并且其所有成员都是静态的。静态成员具有一个版本,无论其封闭类型的实例数量是多少。

  
  静态类与非静态类基本相同,但有一个区别:静态类不能在外部实例化。换句话说,您不能使用new关键字来创建类类型的变量。因为没有实例变量,所以可以使用类名本身访问静态类的成员。

  
  但是,有一个静态构造函数。任何类都可以包含其中一个,包括静态类。它们不能直接调用&不能有参数(除了类本身的任何类型参数)。在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类。看起来像这样:[20]



static class Foo()
{
    static Foo()
    {
        Bar = "fubar";
    }

    public static string Bar { get; set; }
}


静态类通常用作服务,您可以像这样使用它们:


MyStaticClass.ServiceMethod(...);

其它参考1


公开 - 如果您可以看到该类,则可以看到该方法


私有 - 如果您是该类的一部分,那么您可以看到该方法,否则不会。


受保护 - 与私有相同,加上所有后代也可以查看该方法。


静态(类) - 还记得Class和Object之间的区别吗?忘记这一切。它们与静态相同......类是它自己的唯一实例。


静态(方法) - 每当使用此方法时,它将具有独立于其所属类的实际实例的引用框架。

其它参考2


图形概述(简要总结)





对于默认值,如果您没有在前面放置访问修饰符,请参见此处:

C#类和成员(字段,方法等)的默认可见性?


非嵌套


enum                              public
non-nested classes / structs      internal
interfaces                        internal
delegates in namespace            internal
class/struct member(s)            private
delegates nested in class/struct  private


嵌套:


nested enum      public
nested interface public
nested class     private
nested struct    private

其它参考3


关于 Nothing 的问题



  • 默认情况下,命名空间类型是内部的

  • 默认情况下,任何类型成员(包括嵌套类型)都是私有的


其它参考4




using System;

namespace ClassLibrary1
{
    public class SameAssemblyBaseClass
    {
        public string publicVariable = "public";
        protected string protectedVariable = "protected";
        protected internal string protected_InternalVariable = "protected internal";
        internal string internalVariable = "internal";
        private string privateVariable = "private";
        public void test()
        {
            // OK
            Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(publicVariable);

            // OK
            Console.WriteLine(protectedVariable);

            // OK
            Console.WriteLine(internalVariable);

            // OK
            Console.WriteLine(protected_InternalVariable);
        }
    }

    public class SameAssemblyDerivedClass : SameAssemblyBaseClass
    {
        public void test()
        {
            SameAssemblyDerivedClass p = new SameAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }

    public class SameAssemblyDifferentClass
    {
        public SameAssemblyDifferentClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // NOT OK
            // Console.WriteLine(privateVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            //Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }
}





 using System;
        using ClassLibrary1;
        namespace ConsoleApplication4

{
    class DifferentAssemblyClass
    {
        public DifferentAssemblyClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            // Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protectedVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protected_InternalVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protected_InternalVariable);
        }
    }

    class DifferentAssemblyDerivedClass : SameAssemblyBaseClass
    {
        static void Main(string[] args)
        {
            DifferentAssemblyDerivedClass p = new DifferentAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            //Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);

            SameAssemblyDerivedClass dd = new SameAssemblyDerivedClass();
            dd.test();
        }
    }
}

其它参考5


嗯。


请参阅此处:访问修饰符。[22]


简而言之:


Public提供方法或从其他类型/类中键入完整的可见性。


Private仅允许包含私有方法/变量的类型访问私有方法/变量(请注意,嵌套类也可以访问包含类私有方法/变量)。


受保护类似于private,但派生类也可以访问受保护的方法。


没什么是VB.NET相当于null。虽然如果你指的是没有意思是没有访问修饰符,那么它取决于,虽然一个非常粗略的经验法则(当然在C#中)是如果你如果没有明确指定访问修饰符,则方法/变量声明通常为 restricted 。



public class MyClass
{
    string s = "";
}


实际上与以下内容相同:


public class MyClass
{
    private string s = "";
}


当没有明确指定访问修饰符时,链接的MSDN文章将提供完整描述。

其它参考6


公开 - 任何人都可以访问。

私人 - 只能在其所属的类中进行访问。

protected - 只能在类或从类继承的任何对象中访问。


什么都不像null,但在VB中。

静态意味着您拥有该对象的一个​​实例,该方法适用于该类的每个实例。

其它参考7


嗯...


静态意味着您可以在没有类实例的情况下访问该函数。


您可以直接从类定义中访问。

其它参考8


Private的状态表示变量只能由同一个类的对象访问。受保护的状态扩展了该访问权限,以包括该类的后代。


从上面的表格中我们可以看到私人和受保护之间的差别......我认为两者都是相同的...所以需要两个单独的命令


检查MSDN链接以获取更多信息[23]

其它参考9


这些访问修饰符指定您的成员可见的位置。你应该读一读。以IainMH给出的链接为出发点。


静态成员是每个类一个,而不是每个实例一个。

其它参考10


仔细观察您的课程的可访问性。默认情况下,每个人都可以访问公共和受保护的类和方法。


在创建Visual Studio中的新类时,Microsoft也不会非常明显地显示访问修饰符(public,protected等等。关键字)。因此,请仔细考虑并考虑您的类的可访问性,因为它是通向大门的大门。你的实现内部。

其它参考11


我认为这与良好的OOP设计有关。如果您是库的开发人员,则希望隐藏库的内部工作方式。这样,您可以稍后修改库内部工作。因此,您将您的成员和帮助程序方法设置为私有,并且只有接口方法是公共的。应该保护应该覆盖的方法。

其它参考12


从这个答案中重新发布了令人敬畏的图表。



  以下是维恩图中的所有访问修饰符,从更多限制到更多混杂:

  
  private:结果
  

  
  private protected: - 添加在C#7.2中
   [25]

  
  internal:结果
  

  
  protected:结果
  

  
  protected internal:结果
  

  
  public:结果
  


其它参考13


C#总共 6 访问修饰符:


private :使用此辅助功能声明的成员可以在包含类型中可见,任何派生类型,相同程序集中的其他类型或包含程序集之外的类型都不可见。即,访问仅限于包含类型。


protected :使用此辅助功能声明的成员可以在从包含程序集中的包含类型派生的类型中可见,也可以在从包含程序集外部的包含类型派生的类型中可见。即,访问仅限于包含类型的派生类型。


内部:使用此辅助功能声明的成员可以在包含此成员的程序集中可见,对于包含程序集之外的任何程序集都不可见。即,访问仅限于包含程序集。


内部受保护:使用此辅助功能声明的成员可以在从包含程序集内部或外部的包含类型派生的类型中可见,对于包含程序集中的任何类型也是可见的。即,访问仅限于包含汇编或派生类型。


public :使用此辅助功能声明的成员可以在包含此成员的程序集中显示,也可以在引用包含程序集的任何其他程序集中可见。即,访问不受限制。


C#7.2正在增加一个新的可访问性级别:


private protected :使用此辅助功能声明的成员可以在包含的程序集中从此包含类型派生的类型中可见。对于不是从包含类型派生的任何类型,或在包含程序集之外,它是不可见的。即,访问仅限于包含组件内的派生类型。


源包括新的私有保护访问修饰符的示例代码[26]