在C#中,public,private,protected和没有访问修饰符有什么区别?

MrM*_*MrM 701 .net c# asp.net access-modifiers

我所有的大学四年我一直在使用public,并想知道的区别public,privateprotected

还有什么可以static做而不是什么都没有?

mbi*_*ard 977

访问修饰符

上市

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

私人的

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

保护

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

私人保护(在C#7.2中添加)

类型或成员只能通过相同类或结构中的代码访问,或者可以通过同一程序集中的派生类访问,但不能通过其他程序集访问.

内部

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

保护内部

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

如果设置访问修饰符,则使用默认访问修饰符.因此,即使没有设置,也总会有某种形式的访问修饰符.

静态的

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

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

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

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

    public static string Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

MyStaticClass.ServiceMethod(...);
Run Code Online (Sandbox Code Playgroud)

  • 你可以在非静态类中使用静态方法,对吧? (16认同)
  • 是的,它们的行为与我的例子相同. (14认同)
  • "汇编"这个词在这个背景下意味着什么? (6认同)
  • Protected 和 Private Protected 和有什么不一样?对我来说,听起来两者都一样.. (2认同)
  • @goofyui,区别在于“受保护”成员可以在**任何程序集**的派生类中访问。“私有受保护”成员只能在**同一程序集中**的派生类中访问。 (2认同)

Jos*_*ons 156

公共 - 如果您可以看到该类,那么您可以看到该方法

私人 -如果你的部分类,然后就可以看到该方法,否则不是.

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

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

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

  • 在谈论C#时,'对象'可能不是一个好词,因为所有类的基类型都是*System.Object*.'实例'将是一个更好的词,或'对象'(小写'O'). (2认同)

Ste*_*ger 151

图形概述(简要总结)

能见度

对于默认值,如果您没有在前面放置访问修饰符,请参阅此处:
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
Run Code Online (Sandbox Code Playgroud)

嵌套:

nested enum      public
nested interface public
nested class     private
nested struct    private
Run Code Online (Sandbox Code Playgroud)


Pau*_*aul 26

这个答案中重新发布真棒图表.

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

private:
在此输入图像描述

private protected: - 在C#7.2中添加
在此输入图像描述

internal:
在此输入图像描述

protected:
在此输入图像描述

protected internal:
在此输入图像描述

public:
在此输入图像描述


Nar*_*yal 23

在此输入图像描述

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这只是一个简单的解释.由于其他答案有点令人困惑,一半回答:) (4认同)
  • @John Saunders:它通过分离该类在同一个类和该类在不同程序集中的派生类的可见性来区分.此外,他通过展示他的示例代码提供了他如何获得这些信息.所以它实际上增加了其他答案.我的回答可能是由我在回答中的评论引发的. (4认同)
  • “不同程序集中的派生类”-这为另一个答案中已经给出的图表增加了价值。区别是有帮助的,特别是在“受保护的内部”情况下 (2认同)

lep*_*pie 22

关于什么都没有

  • 命名空间类型默认为内部
  • 默认情况下,任何类型成员(包括嵌套类型)都是私有的


use*_*087 12

当前访问修饰符的另一种可视化方法(C#7.2)。希望该架构可以帮助您更轻松地记住它
(单击图像以进行交互式查看。)

交互式访问修饰符svg

外在内

如果您想记住两个单词的访问修饰符,请记住outside-inside

  • 私有受保护私有 外部(同一程序集)受保护 内部(同一程序集)
  • 受保护的内部受保护的 外部(相同的组件)内部的 内部(相同的组件)


Cra*_*gTP 11

嗯.

请参见此处: 访问修饰符.

简而言之:

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

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

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

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

public class MyClass
{
    string s = "";
}
Run Code Online (Sandbox Code Playgroud)

实际上与以下内容相同:

public class MyClass
{
    private string s = "";
}
Run Code Online (Sandbox Code Playgroud)

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


Ton*_*ony 8

公共 - 任何人都可以访问.
private - 只能在类中访问它.
protected - 只能在类或从类继承的任何对象中访问.

没有什么比null更像是在VB中.
静态意味着您拥有该对象的一个​​实例,该方法适用于该类的每个实例.


gbi*_*chi 5

嗯……

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

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


小智 5

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

“从上表中我们可以看到私有和受保护之间的区别......我认为两者是相同的......那么这两个单独的命令需要什么”

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


Lew*_*sey 5

    \n
  • public意味着它可以被任何程序集中的任何类访问,其中包括类本身。
  • \n
  • protected internal意味着它可以被类本身访问(在类定义中),并且可以被当前程序集中的任何类访问,但在程序集之外它只能被继承该类的类访问,或者被类本身(如果它是分部类) \xe2\x80\x93 基本上意味着internal程序集内部和protected程序集外部。
  • \n
  • protected意味着它只能由类本身访问,或者由继承它的类访问,并且该类可以位于任何程序集中
  • \n
  • internal意味着它可以由类本身或程序集中的任何类访问,但在程序集外部根本无法访问,除非由类本身访问(即它是分部类)
  • \n
  • private protected意味着它只能由类本身访问,或者可以由继承它的类访问,并且仅当该类位于当前程序集中时。在程序集之外,它只能由类本身访问(即它是一个分部类) \xe2\x80\x93 基本上结合了internaland protected,或者另一种表达方式是它private在程序集之外和protected内部集会。
  • \n
  • private意味着它只能被类本身访问
  • \n
  • 无访问修饰符:C# 中所有内容的默认访问权限是“您可以为该成员声明的最受限制的访问权限”。,适用private于类中的成员/方法/嵌套类以及internal非嵌套类。
  • \n
\n

在上面的文本中,“accessed”表示通过类类型的对象访问,该对象在类本身的方法中将是隐式this对象,或者该方法可能实例化当前类类型的显式对象并通过那个物体。两者都被认为是由类本身访问,因此访问规则是相同的。这也适用于从静态方法执行的访问,或者当访问静态成员/方法时,除非访问是使用类范围而不是对象执行的。静态类的成员/方法需要显式创建static,否则无法编译。

\n

默认情况下,非嵌套类可以是publicinternal和 are internal。嵌套的类可以是任何访问类型,如果父类是静态的,则它不需要是静态的,它的成员也不需要是静态的。类internal意味着它只能被实例化或者只能从当前程序集访问其静态成员。

\n

internal您可以在嵌套类中拥有公共成员/方法/嵌套类private- 仅访问说明符(在正在进行的访问的完全限定名称中)低于当前正在进行的访问所需的级别阻止访问。

\n

C# 中的继承始终public与 C++ 不同,C++ 可以私有或受保护地继承,然后更改所有从该类继承的类继承的类的访问权限,以及通过对象/通过类型的类范围进行访问从该类私有/受保护地继承的类以及从私有/受保护地继承该类的类继承的类,依此类推。访问被更改,使得所有访问修饰符的限制性小于 或private,并且分别protected被创建。privateprotected

\n