Answers:
该类型或成员可以由同一程序集或引用该程序集的另一个程序集中的任何其他代码访问。
类型或成员只能由相同类或结构中的代码访问。
类型或成员只能由相同类或结构或派生类中的代码访问。
private protected
(在C#7.2中添加)类型或成员只能由相同类或结构中的代码访问,或者只能由同一程序集中的派生类访问,而不能从另一个程序集中访问。
可以通过同一程序集中的任何代码访问类型或成员,但不能从另一个程序集中访问该类型或成员。
该类型或成员可以由同一程序集中的任何代码访问,也可以由另一个程序集中的任何派生类访问。
如果未设置访问修饰符,则使用默认访问修饰符。因此,即使未设置访问修饰符,总会有某种形式。
static
修饰符类上的static修饰符意味着该类无法实例化,并且其所有成员都是静态的。静态成员具有一个版本,无论创建多少个其封闭类型的实例。
静态类与非静态类基本相同,但是有一个区别:静态类不能在外部实例化。换句话说,您不能使用new关键字来创建类类型的变量。因为没有实例变量,所以您可以使用类名本身来访问静态类的成员。
但是,有一个诸如静态构造函数之类的东西。任何类都可以具有其中之一,包括静态类。它们不能直接调用,也不能具有参数(类本身上的任何类型参数除外)。在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类。看起来像这样:
static class Foo()
{
static Foo()
{
Bar = "fubar";
}
public static string Bar { get; set; }
}
静态类通常用作服务,您可以像这样使用它们:
MyStaticClass.ServiceMethod(...);
图形概述(概述)
由于静态类是密封的,因此不能继承它们(从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
此外,它们还有密封关键字,这使类不可继承。
另外,在VB.NET中,关键字有时会有所不同,因此这里是一个备忘单:
公共 -如果您可以看到该类,则可以看到该方法
私有 -如果您是该类的一部分,则可以看到该方法,否则就看不到。
受保护 -与私有相同,所有后代也可以看到该方法。
静态(类) -还记得“类”和“对象”之间的区别吗?算了吧 它们与“静态”相同...类是其自身的唯一实例。
静态(方法) -每当使用此方法时,它都会具有一个独立于其所属类的实际实例的参考框架。
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();
}
}
}
Private Protected
,将是:相同的类= Yes
,相同的程序集,派生的类= Yes
,相同的程序集,任何类= NO
,不同的程序集,派生的类= NO
,不同的程序集,任何class = NO
。还有一个建议是不要更改单词顺序protected internal
,因为这会打破@ user1810087的回答引起的肺炎
嗯
参见此处: 访问修饰符。
简而言之:
Public使方法或类型对其他类型/类具有完全的可见性。
私有仅允许包含私有方法/变量的类型访问私有方法/变量(请注意,嵌套类也可以访问包含类的私有方法/变量)。
保护的类似于私有,除了派生类也可以访问保护的方法。
“无”是VB.NET的等效于null。尽管如果您指的是“ nothing”(无访问修饰符),那么它取决于(尽管很粗略的经验法则(在C#中确实如此)是,如果您未明确指定访问修饰符,则方法/变量声明通常受到限制。即
public class MyClass
{
string s = "";
}
实际上与以下内容相同:
public class MyClass
{
private string s = "";
}
当没有明确指定访问修饰符时,链接的MSDN文章将提供完整的描述。
我认为这与良好的OOP设计有关。如果您是图书馆的开发人员,则想隐藏图书馆的内部作品。这样,您可以稍后修改库的内部工作方式。因此,您将成员和助手方法设置为私有,而只有接口方法是公开的。应该覆盖的方法应受到保护。
C#总共有6个访问修饰符:
私人的:具有此可访问性的成员声明可以在包含类型内看到,对于任何派生类型,同一程序集中的其他类型或包含程序集外部的类型都不可见。即,访问仅限于包含类型。
protected:具有此可访问性的成员声明可以在包含程序集的包含类型派生的类型以及包含程序集之外的包含类型派生的类型中看到。也就是说,访问仅限于包含类型的派生类型。
internal:具有此可访问性声明的成员在包含该成员的程序集中可以看到,对于包含该程序集之外的任何程序集都不可见。也就是说,访问仅限于仅包含程序集。
内部受保护的:声明具有此可访问性的成员在包含程序集内部或外部的包含类型派生的类型内都是可见的,对于包含程序集内的任何类型也可见。也就是说,访问仅限于包含程序集或派生类型。
public:具有此可访问性的成员声明可以在包含该成员的程序集中,或者在引用该包含程序集的任何其他程序集中可见。即,访问不受限制。
C#7.2添加了新的可访问性级别:
private protected:具有此可访问性的成员声明可以在包含程序集的此包含类型派生的类型中看到。对于不是从包含类型派生的任何类型,或者在包含程序集外部的任何类型,它都是不可见的。也就是说,访问仅限于包含程序集内的派生类型。