zoukankan      html  css  js  c++  java
  • C#中,代码能不能访问到private或protected的成员,和当前代码是不是在类型(类、结构体)中有关,和当前代码是不是在类型(类、结构体)的对象实例中无关

    在C#中,privateprotected访问修饰符被广泛应用,微软对它们的定义如下:

    • private:只有同一 class 或 struct 中的代码可以访问该类型或成员。
    • protected:只有同一 class 或者从该 class 派生的 class 中的代码可以访问该类型或成员。

    相信大家对这两个访问修饰符的概念已经很熟悉了,这里不再多述。唯一要注意的是结构体中,不能定义protected的成员,只是本文为了叙述方便,将(类、结构体)写在一起了。

    本文想解释的是privateprotected的成员,能不能被代码访问到,是和当前代码是否在定义privateprotected成员的类型(类、结构体)中有关,而不是说一定要当前代码在定义privateprotected成员的类型(类、结构体)对象实例中,才能访问到它们。也就是说类型(类、结构体)对象实例的privateprotected成员,不是只能通过thisbase关键字才能访问到。

    新建一个.NET Core控制台项目,我们首先来看看下面关于private访问修饰符的代码:

    using System;
    
    namespace NetCoreAccess
    {
        //BaseClass类
        public class BaseClass
        {
            private int intPrivateMember = 1000;
            protected int intProtectedMember = 1000;
    
            //静态方法AccessPrivateMember,访问BaseClass类的private成员intPrivateMember
            public static int AccessPrivateMember(BaseClass baseClass)
            {
                int result = baseClass.intPrivateMember;
    
                BaseClass anotherBaseClass = new BaseClass();
                result = anotherBaseClass.intPrivateMember;
    
                return result;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Press any key to end...");
                Console.ReadKey();
            }
        }
    }

    可以看到,我们可以在BaseClass类的静态方法AccessPrivateMember中,访问到类BaseClass对象实例baseClass和anotherBaseClass的private成员intPrivateMember。这就是因为静态方法AccessPrivateMember,是定义在BaseClass类中的,所以它就可以访问到BaseClass类的private成员intPrivateMember,尽管AccessPrivateMember方法不属于任何BaseClass类的对象实例。

    现在,我们增加关于protected访问修饰符的代码,如下所示:

    using System;
    
    namespace NetCoreAccess
    {
        //BaseClass类
        public class BaseClass
        {
            private int intPrivateMember = 1000;
            protected int intProtectedMember = 1000;
    
            //静态方法AccessPrivateMember,访问BaseClass类的private成员intPrivateMember
            public static int AccessPrivateMember(BaseClass baseClass)
            {
                int result = baseClass.intPrivateMember;
    
                BaseClass anotherBaseClass = new BaseClass();
                result = anotherBaseClass.intPrivateMember;
    
                return result;
            }
        }
    
        //DerivedClass类,继承基类BaseClass
        public class DerivedClass : BaseClass
        {
            //静态方法AccessProtectedMember,访问DerivedClass类中,从BaseClass类继承到的protected成员intProtectedMember
            public static int AccessProtectedMember(DerivedClass derivedClass)
            {
                int result = derivedClass.intProtectedMember;
    
                DerivedClass anotherDerivedClass = new DerivedClass();
                result = anotherDerivedClass.intProtectedMember;
    
                BaseClass baseClass = derivedClass;
                //result = baseClass.intProtectedMember;//编译错误:Error    CS1540    Cannot access protected member 'BaseClass.intProtectedMember' via a qualifier of type 'BaseClass'; the qualifier must be of type 'DerivedClass' (or derived from it)
    
                baseClass = new BaseClass();
                //result = baseClass.intProtectedMember;//编译错误:Error    CS1540    Cannot access protected member 'BaseClass.intProtectedMember' via a qualifier of type 'BaseClass'; the qualifier must be of type 'DerivedClass' (or derived from it)
    
                return result;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Press any key to end...");
                Console.ReadKey();
            }
        }
    }

    可以看到,我们可以在DerivedClass类的静态方法AccessProtectedMember中,访问到类DerivedClass对象实例derivedClass和anotherDerivedClass的protected成员intProtectedMember,这就是因为静态方法AccessProtectedMember,是定义在DerivedClass类中的,所以它就可以访问到类DerivedClass中,从基类BaseClass继承到的protected成员intProtectedMember,尽管AccessProtectedMember方法不属于任何DerivedClass类的对象实例。

    尽管如此,我们可以从AccessProtectedMember方法中被注释掉的代码看到,我们无法通过基类BaseClass的对象实例baseClass来访问protected成员intProtectedMember,会出现编译错误。也许你会想是不是因为AccessProtectedMember是静态方法,所以我们在它里面无法使用BaseClass类的对象实例,来访问到protected成员intProtectedMember,那我们把代码改为如下,添加DerivedClass类的对象实例方法(非静态方法)AccessProtectedMemberWithinInstance,如下所示:

    using System;
    
    namespace NetCoreAccess
    {
        //BaseClass类
        public class BaseClass
        {
            private int intPrivateMember = 1000;
            protected int intProtectedMember = 1000;
    
            //静态方法AccessPrivateMember,访问BaseClass类的private成员intPrivateMember
            public static int AccessPrivateMember(BaseClass baseClass)
            {
                int result = baseClass.intPrivateMember;
    
                BaseClass anotherBaseClass = new BaseClass();
                result = anotherBaseClass.intPrivateMember;
    
                return result;
            }
        }
    
        //DerivedClass类,继承基类BaseClass
        public class DerivedClass : BaseClass
        {
            //静态方法AccessProtectedMember,访问DerivedClass类中,从BaseClass类继承到的protected成员intProtectedMember
            public static int AccessProtectedMember(DerivedClass derivedClass)
            {
                int result = derivedClass.intProtectedMember;
    
                DerivedClass anotherDerivedClass = new DerivedClass();
                result = anotherDerivedClass.intProtectedMember;
    
                BaseClass baseClass = derivedClass;
                //result = baseClass.intProtectedMember;//编译错误:Error    CS1540    Cannot access protected member 'BaseClass.intProtectedMember' via a qualifier of type 'BaseClass'; the qualifier must be of type 'DerivedClass' (or derived from it)
    
                baseClass = new BaseClass();
                //result = baseClass.intProtectedMember;//编译错误:Error    CS1540    Cannot access protected member 'BaseClass.intProtectedMember' via a qualifier of type 'BaseClass'; the qualifier must be of type 'DerivedClass' (or derived from it)
    
                return result;
            }
    
            //对象实例方法AccessProtectedMemberWithinInstance,访问DerivedClass类中,从BaseClass类继承到的protected成员intProtectedMember
            public int AccessProtectedMemberWithinInstance(DerivedClass derivedClass)
            {
                int result = derivedClass.intProtectedMember;
    
                DerivedClass anotherDerivedClass = new DerivedClass();
                result = anotherDerivedClass.intProtectedMember;
    
                BaseClass baseClass = derivedClass;
                //result = baseClass.intProtectedMember;//编译错误:Error    CS1540    Cannot access protected member 'BaseClass.intProtectedMember' via a qualifier of type 'BaseClass'; the qualifier must be of type 'DerivedClass' (or derived from it)
    
                baseClass = new BaseClass();
                //result = baseClass.intProtectedMember;//编译错误:Error    CS1540    Cannot access protected member 'BaseClass.intProtectedMember' via a qualifier of type 'BaseClass'; the qualifier must be of type 'DerivedClass' (or derived from it)
    
                baseClass = this;
                //result = baseClass.intProtectedMember;//编译错误:Error    CS1540    Cannot access protected member 'BaseClass.intProtectedMember' via a qualifier of type 'BaseClass'; the qualifier must be of type 'DerivedClass' (or derived from it)
    
                return result;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Press any key to end...");
                Console.ReadKey();
            }
        }
    }

    从AccessProtectedMemberWithinInstance方法中被注释掉的代码可以看出,我们仍然无法通过BaseClass类的对象实例baseClass,来访问protected成员intProtectedMember,会出现编译错误。这是因为从本质上来说基类BaseClass和子类DerivedClass是两个不同的类,尽管它们之间有继承关系,但是我们在子类DerivedClass的AccessProtectedMember和AccessProtectedMemberWithinInstance方法中,访问到的protected成员intProtectedMember,都还是属于子类DerivedClass的,尽管intProtectedMember成员是通过基类BaseClass继承到的,但是DerivedClass类的intProtectedMember成员,终究是DerivedClass类自己的,并不是BaseClass类的那个intProtectedMember成员,所以我们在AccessProtectedMember和AccessProtectedMemberWithinInstance方法中,无法通过BaseClass类的对象实例baseClass,来访问到BaseClass类的protected成员intProtectedMember,也就合情合理了,因为AccessProtectedMember和AccessProtectedMemberWithinInstance方法实际上是被定义在子类DerivedClass中,并不是在基类BaseClass中。

    好了,其实通过本文,我们就可以了解到privateprotected的成员,能不能被访问到,实际上是和当前代码是否在定义成员的类型(类、结构体)中有关,并不是说只能在定义成员的类型(类、结构体)对象实例代码中才能访问到它们。

    参考文献:

    Access Modifiers (C# Programming Guide)

  • 相关阅读:
    【Java123】JDBC数据库连接池建立
    【招聘123】Some good open positions
    [Java123]Gradle
    4_3:流程控制:循环练习
    4_3:流程控制:while + do while + continue + break
    4_2:流程控制:[ for循环 ] + 断点调试
    4_1:流程控制:分支结构:[ if else ] + [ 三元表达式 ] + [ switch case ]
    3:运算符 + 运算符优先级 [ 逻辑短路 ]
    2_3:变量:[ 类型之间转换 ]
    2_2:变量:[ 五种简单数据类型 ]
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/13365424.html
Copyright © 2011-2022 走看看