微软官方文档
http://msdn.microsoft.com/zh-cn/library/wxh6fsc7(VS.80).aspx
访问修饰符是一些关键字,用于指定声明的成员或类型的可访问性。访问修饰符有四个:
public protected internal private
| 声明的可访问性 | 含义 |
| public | 访问不受限制。 |
| protected | 访问仅限于包含类或从包含类派生的类型。 |
| internal | 访问仅限于当前程序集。 |
| protected internal | 访问仅限于从包含类派生的当前程序集或类型。 |
| private | 访问仅限于包含类型。 |
一个成员或类型只能有一个访问修饰符,使用 protected internal 组合时除外。
命名空间上不允许使用访问修饰符。命名空间没有访问限制。
根据发生成员声明的上下文,只允许某些声明的可访问性。如果在成员声明中未指定访问修饰符,则使用默认的可访问性。
不嵌套在其他类型中的顶级类型的可访问性只能是 internal 或 public。这些类型的默认可访问性是 internal。
嵌套类型是其他类型的成员,它们可以具有下表所示的声明的可访问性。
| 属于 | 默认的成员可访问性 | 该成员允许的声明的可访问性 |
| enum | public | 无 |
| class | private | public protected internal private protected internal |
| interface | public | 无 |
| struct | private | public internal private |
范例如下:
publicTest
namespace publicTest
{
class Point
{
public int x;
//private int x;
//protected int x;
//internal int x;
public int y;
}
}
namespace publicTest
{
class MainClass
{
static void Main()
{
Point p = new Point();
// Direct access to public members:
p.x = 10;
p.y = 15;
Console.WriteLine("x = {0}, y = {1}", p.x, p.y);
Console.ReadLine();
}
}
}
在同一程序集下,定义Point类下的成员为public与internal,可直接通过 MainClass 访问 Point 的公共成员 x 和 y。
protectedTest
namespace protectedTest
{
class A
{
protected int x = 123;
//public int x = 123;
}
}
namespace protectedTest
{
class B : A
{
static void Main()
{
A a = new A();
B b = new B();
// Error CS1540, because x can only be accessed by
// classes derived from A.
// a.x = 10;
// OK, because this class derives from A.
b.x = 10;
//Console.WriteLine("{0} {1}", a.x, b.x);
Console.WriteLine(b.x);
Console.ReadLine();
}
}
}
在B中调用类A的构造函数,创建一个对象a。然后获取a.x会报CS1540错误,在网上也搜了好久。搜到了如下信息:protected类型并不是能够被派生类随心所欲的访问,而是有条件的,访问必须是通过派生类类型发生时,在派生类中的基类的protected类型成员才能够被访问,这里就很清楚了上面的代码并不是通过派生类的类型访问的,而是通过基类的类型访问的,此时此刻,protected和private十分的相似,只不过,protected类型成员能够被派生类所继承并且能够通过派生类类型访问罢了。
namespace protectedTest
{
class Point
{
protected int x;
protected int y;
}
}
namespace protectedTest
{
class DerivedPoint : Point
{
static void Main()
{
DerivedPoint dp = new DerivedPoint();
// Direct access to protected members:
dp.x = 10; dp.y = 15;
Console.WriteLine("x = {0}, y = {1}", dp.x, dp.y);
Console.ReadLine();
}
}
}
privateTest
namespace privateTest
{
class Employee
{
private string name = "FirstName, LastName";
private double salary = 100.0;
public string GetName()
{
return name;
}
public double Salary
{
get { return salary; }
}
}
}
namespace privateTest
{
class MainClass
{
static void Main()
{
Employee e = new Employee();
// The data members are inaccessible (private), so
// then can't be accessed like this:
//string n = e.name;
//double s = e.salary;
// 'name' is indirectly accessed via method:
string n = e.GetName();
// 'salary' is indirectly accessed via property
double s = e.Salary;
Console.WriteLine("{0} {1}",n,s);
Console.ReadLine();
}
}
}
MainClass无法直接访问对象的name和salary成员,需要属性或者方法。C#的类有field(字段)和Attribute(属性)。字段用小写,并且是不对外暴露,也就是说是私有或者是保护变量(id)。外部如果要操作(读、写)这些字段,需要通过对外暴露出来的属性(ID)的get(读)、set(写)操作。
internalTest
namespace internalTest
{
internal class BaseClass
{
public static int intM = 0;
}
//public class BaseClass
//{
// public static int intM = 0;
//}
}
namespace Assembly
{
class TestAccess
{
static void Main()
{
BaseClass myBase = new BaseClass(); // CS0122
}
}
}
不在一个程序集中, “internalTest.BaseClass.BaseClass()”不可访问,因为它受保护级别限制。
使用public
namespace internalTest
{
public class BaseClass_B
{
internal static int intM = 0;
}
}
namespace Assembly
{
public class TestAccess_B
{
static void Main()
{
BaseClass_B myBase = new BaseClass_B(); // Ok.
myBase.intM = 444; // CS0117
}
}
}
会报出错误:无法使用实例引用来访问成员“internalTest.BaseClass_B.intM”;请改用类型名来限定它,因为intM在internalTest中为静态方法。
静态成员也称为共享成员,例如静态属性 静态字段 静态方法;静态成员可以在类的实例之间共享。静态类中只能有静态成员,不能有实例成员,因为静态类不能进行实例化;在非静态类中即可以有静态成员也可以有非静态成员;只要是静态成员 属性 字段 方法,都需要用类名去调用;当类第一次加载的时候(第一次被加载到内存的时候),该类下的所有的静态成员都会被加载,实例成员有多少个对象,就会创建多少个对象;静态成员会被加载到静态存储区,直到程序退出时才会被释放;
修改后代码:
namespace Assembly
{
public class TestAccess_B
{
static void Main()
{
BaseClass_B myBase_B = new BaseClass_B(); // Ok.
BaseClass_B.intM = 444;
}
}
}
本文详细介绍了C#中的访问修饰符,包括public、protected、internal及private等,并通过示例代码展示了不同修饰符在实际编程中的应用。此外,还讨论了如何在不同场景下选择合适的访问级别。
2601

被折叠的 条评论
为什么被折叠?



