C#类访问修饰符

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SigelKoo/article/details/79810810
微软官方文档
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;

       }

    }

}

展开阅读全文

没有更多推荐了,返回首页