771

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

还有什么static做而不是一无所有?

4

17 回答 17

1062

访问修饰符

来自docs.microsoft.com

public

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

private

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

protected

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

private protected(在 C# 7.2 中添加)

类型或成员只能由同一类或结构中的代码或同一程序集的派生类中的代码访问,但不能从另一个程序集中访问。

internal

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

protected internal

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

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

static修饰符

类上的 static 修饰符意味着该类不能被实例化,并且它的所有成员都是静态的。无论创建了多少个其封闭类型的实例,静态成员都有一个版本。

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

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

static class Foo()
{
    static Foo()
    {
        Bar = "fubar";
    }
    
    public static string Bar { get; set; }
}

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

MyStaticClass.ServiceMethod(...);
于 2009-03-05T13:55:02.313 回答
182

图形概览(简而言之)

能见度

由于静态类是密封的,它们不能被继承(从 Object 除外),所以关键字 protected 在静态类上是无效的。



如果您在前面没有放置访问修饰符,则有关默认值,请参见此处:
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

此外,还有 seal-keyword,它使类不可继承。
此外,在 VB.NET 中,关键字有时是不同的,所以这里有一个备忘单:

VB 与 CS 等价物

于 2014-04-11T08:00:45.917 回答
162

Public - 如果你可以看到类,那么你可以看到方法

Private - 如果您是班级的一员,那么您可以看到该方法,否则不能。

受保护- 与私有相同,而且所有后代也可以看到该方法。

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

静态(方法) - 每当您使用此方法时,它都会有一个独立于它所属的类的实际实例的参考框架。

于 2009-03-05T14:26:45.327 回答
46

从这个答案重新发布真棒图表。

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

private
在此处输入图像描述

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

internal
在此处输入图像描述

protected
在此处输入图像描述

protected internal
在此处输入图像描述

public
在此处输入图像描述

于 2018-04-01T10:17:15.323 回答
33

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

交互式访问修饰符 svg

外 内

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

  • 私有保护私有 外部(同一个程序集)受保护 内部(同一个程序集)
  • 受保护的内部受保护的 外部(相同的组件)内部的 内部(相同的组件)
于 2019-02-21T09:24:39.840 回答
24

在此处输入图像描述

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();
        }
    }
}
于 2015-05-24T07:19:38.427 回答
22

关于一无所有的问题

  • 默认情况下,命名空间类型是内部的
  • 默认情况下,任何类型成员,包括嵌套类型都是私有的
于 2009-03-05T17:27:55.187 回答
11

唔。

请参阅此处: 访问修饰符

简而言之:

Public 为其他类型/类提供方法或类型的完全可见性。

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

受保护类似于私有,只是派生类也可以访问受保护的方法。

"Nothing" 相当于 VB.NET 的 null。尽管如果您指的是“无”,意思是“没有访问修饰符”,那么这取决于,尽管一个非常粗略的经验法则(当然在 C# 中)是,如果您没有显式指定访问修饰符,则方法/变量声明通常受到尽可能多的限制。IE

public class MyClass
{
    string s = "";
}

实际上与以下内容相同:

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

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

于 2009-03-05T13:53:57.370 回答
10

public - 任何人都可以在任何地方访问。
private - 只能从它所属的类中访问。
protected - 只能从类中的 with 或从该类继承的任何对象中访问。

除了在 VB 中,没有什么比 null 更好的了。
静态意味着您拥有该对象的一个​​实例,该类的每个实例的方法。

于 2009-03-05T13:55:40.283 回答
4

嗯……

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

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

于 2009-03-05T13:53:14.050 回答
4

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

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

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

于 2010-07-07T08:13:49.003 回答
3

这些访问修饰符指定您的成员可见的位置。您可能应该阅读此内容。以 IainMH 提供的链接为起点。

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

于 2009-03-05T13:52:47.687 回答
3

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

此外,在 Visual Studio 中创建新类时,Microsoft 在显示访问修饰符(public、protected 等关键字)方面并不是很明确。因此,请注意并考虑您的类的可访问性,因为它是您实现内部的大门。

于 2009-03-05T14:21:00.770 回答
3
  • public意味着它可以被任何程序集中的任何类访问,包括类本身。
  • protected internal意味着它可以被类本身访问(在类定义中),并且它可以被当前程序集中的任何类访问,但在程序集之外它只能被继承该类的类访问,或者被类本身(如果它是一个部分类)——基本上它意味着internal在程序集内部和程序集protected之外。
  • protected意味着它只能由类本身访问,或者由继承它的类访问,并且该类可以在任何程序集中
  • internal意味着它可以被类本身或程序集中的任何类访问,但在程序集之外根本不能访问,除非类本身(即它是一个部分类)
  • private protected意味着它只能被类本身访问,或者它可以被继承它的类访问,并且只有当该类在当前程序集中时。在程序集之外,它只能由类本身访问(即它是一个部分类)——基本上结合了internaland protected,或者另一种说法是它private在程序集之外和程序集之protected内。
  • private意味着它只能被类本身访问
  • 无访问修饰符:C# 中所有内容的默认访问权限是“您可以为该成员声明的最受限制的访问权限”。private用于类中的成员/方法/嵌套类和internal非嵌套类。

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

默认情况下,未嵌套的类既可以是,也public可以internalinternal。嵌套的类可以是任何访问类型,如果父类是静态的,它不需要是静态的,它的成员也不需要。一个internal类意味着它只能被实例化,或者它的静态成员只能从当前程序集中访问。

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

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

于 2021-03-31T15:32:02.780 回答
2

我认为这与良好的 OOP 设计有关。如果你是一个库的开发者,你想隐藏你的库的内部工作。这样,您可以稍后修改您的库内部工作。所以你把你的成员和辅助方法设置为私有的,只有接口方法是公共的。应该被覆盖的方法应该受到保护。

于 2009-03-05T13:57:36.440 回答
2

C# 总共有6 个访问修饰符:

private:使用此可访问性声明的成员可以在包含类型中可见,它对任何派生类型、同一程序集中的其他类型或包含程序集之外的类型不可见。即,访问仅限于包含类型。

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

internal:使用此可访问性声明的成员可以在包含此成员的程序集中可见,它对包含程序集之外的任何程序集都不可见。即,访问仅限于包含程序集。

internal protected:使用此可访问性声明的成员可以在从包含类型派生的类型中可见,该类型在包含程序集内部或外部,它对包含程序集内的任何类型也是可见的。即,访问仅限于包含程序集或派生类型。

public:使用此可访问性声明的成员可以在包含此成员的程序集中或任何其他引用包含程序集的程序集中可见。即,访问不受限制。

在 C# 7.2 中,添加了新级别的可访问性:

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

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

于 2017-12-20T09:27:01.030 回答
0

C# 的所有访问修饰符的描述

在此处输入图像描述

于 2020-03-03T19:32:39.560 回答