您的位置:新葡亰496net > 奥门新萄京娱乐场 > 新葡亰496net访问修饰符,中访问修饰符

新葡亰496net访问修饰符,中访问修饰符

发布时间:2019-11-30 06:16编辑:奥门新萄京娱乐场浏览(136)

    去年12月份,随着Visual Studio 2017 Update 15.5的发布,Visual C#迎来了它的最新版本:7.2. 在这个版本中,有个让人难以理解的新特性,就是private protected访问修饰符(Access Modifier)。至此,C#语言的访问修饰符有以下几种:

    新葡亰496net 1

    一、继承

    4个访问修饰符(是添加到类、结构或成员声明的关键字)

    C# 【方法】默认访问级别 : private

    • private
    • protected
    • public
    • internal
    • internal protected
    • private protected

    用通过代码:

    1、类成员的访问

     

    C# 【类】和【结构体】默认访问级别 : internal

    新葡亰496net,既然有了private和protected,那么private protected又是什么?它跟internal protected又有什么关系?本文简单介绍一下。

     类内部

    使用场合

    Public:公有的,是类型和类型成员的访问修饰符。对其访问没有限制。


    private protected是怎么回事

    在解释private protected之前,首先让我们回顾一下internal protected访问修饰符。internal protected表示,相同程序集(Assembly)中的其它类型,或者当前类的子类,具有访问该类中internal protected成员的能力,可以用下图表示:

    新葡亰496net 2

    在上图中:

    • 程序集A中的X类,可以访问A类中的Method方法
    • 程序集A中的B类,可以重载A类中的Method方法,B类中的其它成员也可以访问A类中的Method
    • 程序集B中的C类,可以重载A类中的Method方法,C类中的其它成员也可以通过base.Method()访问A类中的Method
    • 程序集B中C类的Method方法重载了A类的Method方法,因此,internal关键字被去掉,于是,程序集B中的Y类,无法访问C类中的Method方法

    因此,internal protected表示internal或者protected。

    然而,private protected表示,仅有相同程序集(Assembly)中继承于当前类型的类,才能访问该类中private protected成员。换句话说,private protected就是访问者必须在相同程序集中(internal),同时还必须是被访问类型的子类(protected),可以用下图表示:

    新葡亰496net 3

    因此,private protected表示internal并且protected。

    新葡亰496net 4using System;
    新葡亰496net 5class Mod
    新葡亰496net 6{
    新葡亰496net 7    void defaultMethod()
    新葡亰496net 8    {
    新葡亰496net 9        Console.WriteLine("this is a default method");
    新葡亰496net 10    }
    新葡亰496net 11
    新葡亰496net 12    public void publicMethod()
    新葡亰496net 13    {
    新葡亰496net 14        Console.WriteLine("this is a public method");
    新葡亰496net 15
    新葡亰496net 16    }
    新葡亰496net 17    private void privateMethod()
    新葡亰496net 18    {
    新葡亰496net 19        Console.WriteLine("this is a private method");
    新葡亰496net 20    }
    新葡亰496net 21
    新葡亰496net 22    internal void internalMethod()
    新葡亰496net 23    {
    新葡亰496net 24        Console.WriteLine("this is a internal method");
    新葡亰496net 25    }
    新葡亰496net 26
    新葡亰496net 27    protected void protectedMethod()
    新葡亰496net 28    {
    新葡亰496net 29        Console.WriteLine("this is a protected method");
    新葡亰496net 30    }
    新葡亰496net 31
    新葡亰496net 32    protected internal void protectInternalMethod()
    新葡亰496net 33    {
    新葡亰496net 34        Console.WriteLine("this is a protected internal method");
    新葡亰496net 35    }
    新葡亰496net 36
    新葡亰496net 37    static void Main()
    新葡亰496net 38    {
    新葡亰496net 39        Mod mod=new Mod();
    新葡亰496net 40        mod.defaultMethod();
    新葡亰496net 41        mod.publicMethod();
    新葡亰496net 42        mod.privateMethod();
    新葡亰496net 43        mod.internalMethod();
    新葡亰496net 44        mod.protectedMethod();
    新葡亰496net 45        mod.protectInternalMethod();
    新葡亰496net 46    }
    新葡亰496net 47
    新葡亰496net 48}

    C#2.0

    Internal:内部的,是类型和类型成员的访问修饰符。同一个程序集中的所有类都可以访问

    1.命名空间下的元素的访问修饰符

    private protected何时使用

    理论上讲,private protected完善了C#语言的封装性,提供了另一层级别的成员访问保护,听起来感觉让人费解又没什么用。那么,什么时候使用这个访问修饰符呢?现假设你正在设计一个框架,其中有个类,它提供对象存储功能,它的职责是保存给定的对象,而它的每一种实现都需要依赖于一个对象的序列化机制,比如:

    public sealed class SerializationHelper
    {
        public string Serialze(object s)
        {
            using (var memoryStream = new MemoryStream())
            {
                var serializer = new XmlSerializer(s.GetType());
                serializer.Serialize(memoryStream, s);
                return Encoding.UTF8.GetString(memoryStream.ToArray());
            }
        }
    }
    
    public abstract class DataStorage
    {
        private readonly SerializationHelper serializer = new SerializationHelper();
        protected SerializationHelper Serializer => serializer;
        protected abstract void SaveObject(object obj);
    }
    
    public sealed class InMemoryDataStorage : DataStorage
    {
        private readonly List<string> serializedData = new List<string>();
        protected override void SaveObject(object obj) 
            => serializedData.Add(Serializer.Serialze(obj));
    }
    

    上面的代码中,SerializationHelper提供了一种将对象序列化成XML字符串的机制;DataStorage是所有对象数据存储的基类,它当然也为其子类提供了一个访问对象序列化器的方式。由于这个对象序列化器是提供给其子类调用的,因此,DataStorage中的Serializer属性是protected的。最后,InMemoryDataStorage继承了DataStorage,通过调用由基类提供的Serializer属性,实现了SaveObject方法。

    整个实现当然没有问题。可是,通过审核所有类型的可见性,我们发现,我们不打算将SerializationHelper这个类暴露给外界,也就是不希望其它的程序集能够直接访问SerializationHelper类,于是,我们将它设置成internal的。也就是:

    internal sealed class SerializationHelper
    {
        public string Serialze(object s)
        {
            using (var memoryStream = new MemoryStream())
            {
                var serializer = new XmlSerializer(s.GetType());
                serializer.Serialize(memoryStream, s);
                return Encoding.UTF8.GetString(memoryStream.ToArray());
            }
        }
    }
    

    好了,问题来了,编译器开始抱怨了,说SerializationHelper类的访问级别比DataStorage.Serializer属性的访问级别要低:

    新葡亰496net 49

    道理显而易见:DataStorage.Serializer属性在DataStorage的子类中即可访问,这个子类可以是在DataStorage所在的程序集中,也可以是在另一个程序集中。然而,这个属性的依赖类型:SerializationHelper类,却只能在DataStorage所在的程序集中才能被访问。

    于是,能量巨大的private protected闪亮登场。将DataStorage.Serializer属性的访问修饰符从protected改为private protected,问题就解决了:

    internal sealed class SerializationHelper
    {
        public string Serialze(object s)
        {
            using (var memoryStream = new MemoryStream())
            {
                var serializer = new XmlSerializer(s.GetType());
                serializer.Serialize(memoryStream, s);
                return Encoding.UTF8.GetString(memoryStream.ToArray());
            }
        }
    }
    
    public abstract class DataStorage
    {
        private readonly SerializationHelper serializer = new SerializationHelper();
        private protected SerializationHelper Serializer => serializer;
        protected abstract void SaveObject(object obj);
    }
    
    public sealed class InMemoryDataStorage : DataStorage
    {
        private readonly List<string> serializedData = new List<string>();
        protected override void SaveObject(object obj) 
            => serializedData.Add(Serializer.Serialze(obj));
    }
    

    不过,一旦使用了private protected访问修饰符,DataStorage.Serializer属性就只能在DataStorage所在的程序集的子类中访问了。

    D:/Project/handing/char>Method1
    this is a default method
    this is a public method
    this is a private method
    this is a internal method
    this is a protected method
    this is a protected internal method

    Visual Basic 2005

    Private:私有的,是一个成员访问修饰符。只有在声明它们的类和结构中才可以访问。

    public: 同一程序集的其他任何代码或引用该程序集的其他程序集都可以访问该类型或成员。

    private protected如何使用

    private protected访问修饰符是C# 7.2的新特性。自从使用Roslyn编译器服务的C# 6.0开始,C#编译器的版本更新就可以与.NET Framework和Visual Studio的发布分离开来了。这一点在C# 7.x(包括7.1和7.2)的发布中逐步显现出来。在Visual Studio 2017的编译高级选项中,开发人员可以很方便地选择所需的C#版本:

    新葡亰496net 50

    如上图所述,在C#项目上点右键,在项目属性的Build标签页中,点击Advanced按钮,在Advanced Build Settings对话框中,通过Language version下拉框来选择所需的C#语言版本。其中:

    • C# latest major version (default):C#最新的主版本,也就是与Visual Studio一起发布的主要版本,在VS2017上对应C# 7.0
    • C# latest minor version (latest):C#的最新版,通常通过VS2017的升级包获得

    要使用private protected访问修饰符,则需要在此选择C# latest minor version (latest),或者C# 7.2.

     子类

    说明

    Protected::受保护的,是一个成员访问修饰符。只能在它的类和它的派生类中访问。

    internal: 同一程序集中的任何代码都可以访问该类型或成员,但其他程序集不可以访问。【能够修饰类的访问修饰符只有 internal 和 public】

    总结

    本文对C# 7.2的新特性:private protected访问修饰符进行了解析,并通过案例来说明它的应用场景以及Visual Studio 2017对于C#新特性的支持。

    新葡亰496net 51using System;
    新葡亰496net 52class Mod
    新葡亰496net 53{
    新葡亰496net 54    void defaultMethod()
    新葡亰496net 55    {
    新葡亰496net 56        Console.WriteLine("this is a default method");
    新葡亰496net 57    }
    新葡亰496net 58
    新葡亰496net 59    public void publicMethod()
    新葡亰496net 60    {
    新葡亰496net 61        Console.WriteLine("this is a public method");
    新葡亰496net 62
    新葡亰496net 63    }
    新葡亰496net 64    private void privateMethod()
    新葡亰496net 65    {
    新葡亰496net 66        Console.WriteLine("this is a private method");
    新葡亰496net 67    }
    新葡亰496net 68
    新葡亰496net 69    internal void internalMethod()
    新葡亰496net 70    {
    新葡亰496net 71        Console.WriteLine("this is a internal method");
    新葡亰496net 72    }
    新葡亰496net 73
    新葡亰496net 74    protected void protectedMethod()
    新葡亰496net 75    {
    新葡亰496net 76        Console.WriteLine("this is a protected method");
    新葡亰496net 77    }
    新葡亰496net 78
    新葡亰496net 79    protected internal void protectInternalMethod()
    新葡亰496net 80    {
    新葡亰496net 81        Console.WriteLine("this is a protected internal method");
    新葡亰496net 82    }
    新葡亰496net 83
    新葡亰496net 84}
    新葡亰496net 85
    新葡亰496net 86class Test
    新葡亰496net 87{
    新葡亰496net 88        static void Main()
    新葡亰496net 89            {
    新葡亰496net 90                Mod mod=new Mod();
    新葡亰496net 91            //    mod.defaultMethod();
    新葡亰496net 92                mod.publicMethod();
    新葡亰496net 93            //    mod.privateMethod();
    新葡亰496net 94                mod.internalMethod();
    新葡亰496net 95            //    mod.protectedMethod();
    新葡亰496net 96                mod.protectInternalMethod();
    新葡亰496net 97            }
    新葡亰496net 98}

    Type

        protected internal:访问级别为 internal 或 protected。即,“同一个程序集中的所有类,以及所有程序集中的子类都可以访问

    private: 同一类和结构的代码可以访问该类型和成员。

     

    (指类,接口等类型)

    注意点:

    protected: 同一类和派生(继承特性)类中的代码可以访问该类型和成员。

    D:/Project/handing/char>Method2
    this is a public method
    this is a internal method
    this is a protected internal method

    public

      一个成员或类型只能有一个访问修饰符,使用 protected internal组合时除外。

    protected internal:  同一程序集中的任何代码或其他程序集中的任何派生类都可以访问该类型或成员。

     

    public

          如果在成员声明中未指定访问修饰符,则使用默认的可访问性

    MSDN提示 :

    程序集内

    访问不受限制

       类型成员默认的可访问性

    1) 派生类的可访问性不能高于其基类型。换句话说,不能有从内部类 A 派生公共类 B。如果允许这种情况,将会使 A 成为公共类,因为 A 的所有受保护的成员或内部成员都可以从派生类访问。

    新葡亰496net 99using System;
    新葡亰496net 100class Mod
    新葡亰496net 101{
    新葡亰496net 102    void defaultMethod()
    新葡亰496net 103    {
    新葡亰496net 104        Console.WriteLine("this is a default method");
    新葡亰496net 105    }
    新葡亰496net 106
    新葡亰496net 107    public void publicMethod()
    新葡亰496net 108    {
    新葡亰496net 109        Console.WriteLine("this is a public method");
    新葡亰496net 110
    新葡亰496net 111    }
    新葡亰496net 112    private void privateMethod()
    新葡亰496net 113    {
    新葡亰496net 114        Console.WriteLine("this is a private method");
    新葡亰496net 115    }
    新葡亰496net 116
    新葡亰496net 117    internal void internalMethod()
    新葡亰496net 118    {
    新葡亰496net 119        Console.WriteLine("this is a internal method");
    新葡亰496net 120    }
    新葡亰496net 121
    新葡亰496net 122    protected void protectedMethod()
    新葡亰496net 123    {
    新葡亰496net 124        Console.WriteLine("this is a protected method");
    新葡亰496net 125    }
    新葡亰496net 126
    新葡亰496net 127    protected internal void protectInternalMethod()
    新葡亰496net 128    {
    新葡亰496net 129        Console.WriteLine("this is a protected internal method");
    新葡亰496net 130    }
    新葡亰496net 131
    新葡亰496net 132
    新葡亰496net 133}
    新葡亰496net 134class Modl : Mod
    新葡亰496net 135{
    新葡亰496net 136    static void Main()
    新葡亰496net 137    {
    新葡亰496net 138        Modl mod=new Modl();
    新葡亰496net 139            
    新葡亰496net 140    //    mod.defaultMethod();
    新葡亰496net 141        mod.publicMethod();
    新葡亰496net 142    //    mod.privateMethod();
    新葡亰496net 143新葡亰496net访问修饰符,中访问修饰符。        mod.internalMethod();
    新葡亰496net 144        mod.protectedMethod();
    新葡亰496net 145        mod.protectInternalMethod();
    新葡亰496net 146    }
    新葡亰496net 147    
    新葡亰496net 148
    新葡亰496net 149
    新葡亰496net 150}

    internal

    属于

    默认的成员可访问性

    该成员允许的声明的可访问性

    enum

    public

    class

    private

    public

    protected

    internal

    private

    protected internal

    interface

    public

    struct

    private

    public

    internal

    private

    2) 成员的可访问性决不能高于其包含类型的可访问性。

     

    Friend

           

    3) 可以使用五种访问类型中的任何一种来声明类成员(包括嵌套的类和结构)。

    D:/Project/handing/char>Method3
    this is a public method
    this is a internal method
    this is a protected method
    this is a protected internal method

    访问范围仅限于同一程序集

    Internal 和protected internal 详解(即什么是同一个程序集)

    接口(interface )

    程序集外

    Member

     

    接口成员访问修饰符默认为public,且不能显示使用访问修饰符。

    放在同一个NAMESPACE中,区别于JAVA的包。

    (指类型中的成员,比如类中的字段)

      示例1:(这里同一个程序集指同一个命名空间)

    为了多态,接口不能被实例化;子类实现接口的方法时,不需要任何关键字,直接实现即可;接口存在的意义就是为了多态。

     D:/Project/handing/04_01>csc /target:library Method4.cs Microsoft (R) Visual C# 2005 编译器 版本 8.00.50727.42
    用于 Microsoft (R) Windows (R) 2005 Framework 版本 2.0.50727
    版权所有 (C) Microsoft Corporation 2001-2005。保留所有权利。

    public

    Class1:

    接口中只能有方法、属性、索引器、事件,不能有字段和构造函数。

    D:/Project/handing/04_01>csc /r:Method4.dll Method5.cs Microsoft (R) Visual C# 2005 编译器 版本 8.00.50727.42
    用于 Microsoft (R) Windows (R) 2005 Framework 版本 2.0.50727
    版权所有 (C) Microsoft Corporation 2001-2005。保留所有权利。

    public

     

    类(class)

    D:/Project/handing/04_01>Method5
    this is a public method

    访问不受限制

     using System;

    构造函数默认为public 访问修饰符。

    Method4.cs

    internal

    using System.Collections.Generic;

    析构函数不能显示使用访问修饰符且默认为private 访问修饰符。

    新葡亰496net 151using System;
    新葡亰496net 152namespace 4
    新葡亰496net 153{
    新葡亰496net 154    public class Mod
    新葡亰496net 155        {
    新葡亰496net 156            void defaultMethod()
    新葡亰496net 157            {
    新葡亰496net 158                Console.WriteLine("this is a default method");
    新葡亰496net 159            }
    新葡亰496net 160
    新葡亰496net 161            public void publicMethod()
    新葡亰496net 162            {
    新葡亰496net 163                Console.WriteLine("this is a public method");
    新葡亰496net 164
    新葡亰496net 165            }
    新葡亰496net 166            private void privateMethod()
    新葡亰496net 167            {
    新葡亰496net 168                Console.WriteLine("this is a private method");
    新葡亰496net 169            }
    新葡亰496net 170
    新葡亰496net 171            internal void internalMethod()
    新葡亰496net 172            {
    新葡亰496net 173                Console.WriteLine("this is a internal method");
    新葡亰496net 174            }
    新葡亰496net 175
    新葡亰496net 176            protected void protectedMethod()
    新葡亰496net 177            {
    新葡亰496net 178                Console.WriteLine("this is a protected method");
    新葡亰496net 179            }
    新葡亰496net 180
    新葡亰496net 181            protected internal void protectInternalMethod()
    新葡亰496net 182            {
    新葡亰496net 183                Console.WriteLine("this is a protected internal method");
    新葡亰496net 184            }
    新葡亰496net 185
    新葡亰496net 186
    新葡亰496net 187        }
    新葡亰496net 188}
    新葡亰496net 189

    Friend

    using System.Text;

    类的成员默认访问修饰符为 private。

    Method5.cs

    访问范围仅限于同一程序集

     

    枚举(enum)

     

    protected

    namespace Example05Lib

    枚举类型成员默认为public 访问修饰符,且不能显示使用修饰符。

    新葡亰496net 190using 4;
    新葡亰496net 191using System;
    新葡亰496net 192public class Test
    新葡亰496net 193{
    新葡亰496net 194    public    static void Main()
    新葡亰496net 195    {
    新葡亰496net 196        Mod mod=new Mod();
    新葡亰496net 197        mod.defaultMethod();
    新葡亰496net 198        mod.publicMethod();
    新葡亰496net 199        mod.privateMethod();
    新葡亰496net 200        mod.internalMethod();
    新葡亰496net 201        mod.protectedMethod();
    新葡亰496net 202        mod.protectInternalMethod();
    新葡亰496net 203    }
    新葡亰496net 204
    新葡亰496net 205}

    protected

    {    

    结构(struct)

    以下摘自:

    访问范围限于自己或派生出来的子类型

    public class Class1   

    结构成员默认为private 修饰符。

    msdn的解释如下:internal指的是同一个程序集,内部成员和类型才是可以访问的.内部访问通常用于基于组件的开发,因为它使一组组件能够以私有方式进行合作,而不必向应用程序代码的其余部分公开

    Protected internal

     {       

    结构成员无法声明为 protected 成员,因为结构不支持继承。

    一个成员或类型只能有一个访问修饰符,使用 protectedinternal 组合时除外。

    Protected Friend

     internal String strInternal = null;       

    嵌套类型

    命名空间上不允许使用访问修饰符。命名空间没有访问限制。

    在同一程序集内访问不受限制,在不同程序集中仅由此类型派生出来的子类型可访问

    public String strPublic;       

    嵌套类型的默认访问修饰符为 private。 和类,结构的成员默认访问类型一致。

    根据发生成员声明的上下文,只允许某些声明的可访问性。如果在成员声明中未指定访问修饰符,则使用默认的可访问性。

    private

    internal protected String strInternalProtected = null;   


    不嵌套在其他类型中的顶级类型的可访问性只能是 internal 或 public。这些类型的默认可访问性是 internal。

    private

    }

    除了权限修饰符外还有四个修饰符 sealed,abstract,virtual,partial (这4个修饰符可以和上面5个权限修饰符一起用,可以加在权限修饰符前面或后面),

    嵌套类型是其他类型的成员,它们可以具有下表所示的声明的可访问性。

    仅自己可以访问

    }

    密封类(sealed)

    属于 默认的成员可访问性 该成员允许的声明的可访问性

    enum

    public

    class

    private

    public

    protected

    internal

    private

    protected internal

    interface

    public

    struct

    private

    public

    internal

    private

    1)public、private和protected的区别:

    Class2:

    sealed 只能用来修饰 class,表示 class 不能被继承。

    区别JAVA

    新葡亰496net 206

     

    抽象方法(abstract)

    Java用三个关键字在类的内部设定边界:
    public、private、 protected。它们的含义和用法非常易懂。这些“访问指定词”(access specifier)决定了紧跟其后被定义的东西可以被谁使用。
    public表示紧随其后的元素对任何人都是可用的。
    而private这个关键字表示除类型创建者和类型的内部方法之外的任何人都不能访问的元素。private就像你与客户端程序员之间的一堵砖墙,如果有人试图访问private成员,就会在编译时得到错误信息。
    protected关键字与private作用相当,差别仅在于继承的类可以访问protected成员,但是不能访问private成员。

    在子类中引用:

    using System; using System.Collections.Generic; using System.text

    1.需要用 abstract 关键字标记。

    C#的访问修饰符:

    新葡亰496net 207

     

    2.抽象方法无法声明主体。

         Public:可被所属类和成员以及不属于类的成员访问.

    2)static: 对变量的静态设置(累加求和)

    namespace Example05Lib {    class Class2  {    private String tmpStr=new Class1().strInternal;    private String tmpStr=new Class1().strInternalProtected;    private String tmpStr=new Class1().strPublic;  } }

    3.抽象成员必须包含在抽象类中。

    所修饰类的成员

    在父类中的方法:
    新葡亰496net 208

    1.1结果: Class2 类可以访问到 Class1 的 strInternal 成员,当然也可以访问到 strInternalProtected 成员,因为他们在同一个程序集里

    4.由于抽象成员没有任何实现,所以子类必须将抽象成员重写。

    可在任何情况下通过类的对象和类成员被使用.

    在子类中的方法:

     

    5.抽象类不能实例化,抽象类的作用就是为了让子类继承。

    所修饰的类类型

    新葡亰496net 209

     

    6.抽象类中可以包括抽象成员,可以包括有具体代码的成员。

           可在任何情况下被类的访问级别的类继承.

    3)internal

    Class3:

    7.抽象方法不能用 static 修饰。

           Internal:**可被当前程序集访问           **

    新葡亰496net 210

     

    虚方法(virtual)

    所修饰类的成员

    //在某个类中没有任何可访问性关键字在他前面,它就是internal的。

    using System; using System.Collections.Generic; using System.text using Example05Lib

    1.父类中如果有方法需要让子类重写,则可以将该方法标记为 virtual。

    在统一”解决方案”里的使用与Public相同(与命名空间无关).出了解决方案则不可被使用.

    internal class A     

    namespace Example05  {   class Program   {      class Class3:Class1      {         public Class3()          {             base.StrInternalProtected;              base.strPublic;           }         }   } }

    2.虚方法在父类中必须声明主体,哪怕是【空实现】。

                  所修饰的类类型(其为类的默认修饰符)

         {

    1.2结果:Class3 类无法访问到 Class1 的 strInternal 成员,因为它们不在同一个程序集里。但却可以访问到 strInternalProtected成员,因为 Class3 是 Class1 的继承类。

    3.虚方法子类可以重写(override),也可以不重写。

    在统一”解决方案”中,可被相同级别的类继承(也就是说被Internal修饰的类),不可被访问就别比自己高的类继承(Public修饰的类).

            internal int InternalI = 0;

     

    同时,在不同”解决方案”中,类类型不可被使用.

        }

     

           Protected:可被所属类或派生自所属类的类型访问.

    它完全等同于:

     

                  所修饰类的成员

     class A   //在某个类中没有任何可访问性关键字在他前面,它就是internal的。

    using System; using System.Collections.Generic; using System.text using Example05Lib namespace Example05  { class Program {    static void Main(string[] args)    {       String tmpStr=new Class1().strPublic;     } } }

    1.      可被类的内部对象(隐指针this) 和类成员使用,以及在类的内部所声明的类的对象使用.

        {

    1.3结果:无法访问到 strInternalProtected 与strInternal 成员,因为它们既不在同一个程序集里也不存在继承关系

    2.      在其他类中声明的自身类的对象却不可访问自身的protected成员.

            internal int InternalI = 0;

     

    3.      在同一”命名空间”或不同”命名空间”下,派生自所属类的类就继承了父类的protected以及访问级别以上的类成员,所以他的使用与自身声明的成员无异,其规则参照上两条.

        }

     

    所修饰的类类型

    新葡亰496net 211

    示例2(在这里同一个程序集是指同一个.cs文件,不同的.cs文件的命名空间省略)

           其修饰符不能修饰类.

    它完全等同于:

     

           Private:仅所属类的成员才可以访问

    新葡亰496net 212

    2.1该示例包含两个文件:Assembly1.cs 和 Assembly2.cs。第一个文件包含内部基类 BaseClass。在第二个文件中,实例化BaseClass 的尝试将产生错误。

                  所修饰类的成员(其为类成员的默认修饰符)

    2、多态:当出现继承关系,就会伴随出现多态;简单的理解就是,子类不仅继承了父类的所有属性和方法,每一个子类又会有属于自己的个性的属性和方法。

    internal class BaseClass

    1.      可被类的内部对象和类成员使用,以及在类的内部所声明的类的对象使用.

    新葡亰496net 213

    {

    2.      在其他类中声明的自身类的对象也不可访问自身的private成员.

    3、方法重载、隐藏与虚方法调用

       public static int intM = 0;

    3.      任何情况下,private成员不可被派生类继承.

    由于子类对象汇集了父类和子类的所有公共方法,有些方法父类和子类有重复的方法,所以调用时会有许多问题出现。

    }

    所修饰的类类型

    子类方法与父类方法之间的关系有三种:

    class TestAccess

           其修饰符不能修饰类.

    1)扩充:子类方法,父类没有;

    {


    2)重载:子类有父类的同名函数,但参数类型或数目不一样;

       static void Main()

    static:static 修饰符指明成员属于类本身而不属于类的实例。即使创建了类的多个实例,给定应用程序中只存在 static 成员的一个副本。
    您只能通过对类的引用(而不是对实例的引用)来访问 static 成员。但是,在类成员声明中,可以通过 this 对象来访问 static 成员。

    3)完全相同:子类方法与父类方法从方法名称到参数类型完全一样。

       {

    sealed:sealed 修饰符可以应用于类、实例方法和属性。密封类不能被继承。密封方法会重写基类中的方法,
    但其本身不能在任何派生类中进一步重写。当应用于方法或属性时,sealed 修饰符必须始终与 override(C# 参考) 一起使用。

    新葡亰496net 214

          BaseClass myBase = new BaseClass();   // CS0122

    abstract:在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。
    因为抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })。例如:public abstract void MyMethod();

    在主函数中调用:

       }

    extern 修饰符用于声明在外部实现的方法。extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 属性一起使用;在这种情况下,该方法还必须声明为 static;
    使用 extern 修饰符意味着方法在 C# 代码的外部实现,而使用 abstract 修饰符意味着在类中未提供方法实现。
    同样没有方法体

    新葡亰496net 215

    }

    virtual:与abstract类似,只是虚方法必须实现,抽象方法可以不实现

    【练习1】方法重载:

    2.2 使用与示例 1 中所用的文件相同的文件,并将 BaseClass 的可访问性级别更改为 public。还将成员 IntM 的可访问性级别更改为 internal。在此例中,您可以实例化类,但不能访问内部成员。

    protected:protected 关键字是一个成员访问修饰符。受保护成员在它的类中可访问并且可由派生类访问。
        类的实例也不能访问protected成员.

    新葡亰496net 216

    public class BaseClass

    private:是一个成员访问修饰符。私有访问是允许的最低访问级别。私有成员只有在声明它们的类和结构体中才是可访问的

    【练习2】方法重写:在子类同名方法前加override,表明对父类同名方法进行了重写。父类

    {

    readonly 关键字与 const 关键字不同。const 字段只能在该字段的声明中初始化。readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。另外,const 字段为编译时常数,而 readonly 字段可用于运行时常数,

    子类默认的是new;

       internal static int intM = 0;

    volatile 关键字表示字段可能被多个并发执行线程修改。声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈现的都是最新的值

    父类默认的是override:

    }

    1)加override:(只有当子类转化成父类时起作用)执行子类的方法(子类方法覆盖了父类方法)

    public class TestAccess

    2)不加override:变量名后.(点)哪个类就执行该类的方法。

    {

    新葡亰496net 217

       static void Main()

    新葡亰496net 218

       {

    新葡亰496net 219

          BaseClass myBase = new BaseClass();   // Ok.

     

          BaseClass.intM = 444;    // CS0117

     

       }

     

    }

     

     

    示例3

     

    对于一些大型的项目,通常由很多个DLL文件组成,引用了这些DLL,就能访问DLL里面的类和类里面的方法。比如,你写了一个记录日志的DLL,任何项目只要引用此DLL就能实现记录日志的功能,这个DLL文件的程序就是一个程序集。

    如果你记录日志的程序集是这么定义的

    namespace LogerHelper

    {

        internal class aa

        {

             public void bb()

             {

                 return "";

             }

        }

     

        public class Write

        {

            public void WriteIn(string content)

            {

                class x = new aa();   

                x.bb();

            }

        }

    }

     

    当另一个项目引用了此DLL

    它可以这么访问 

    LogerHelper.Write x = new LogerHelper.Write();

    x.WriteIn("");

     

    但不可以这么访问

    LogerHelper.aa x = new LogerHelper.aa();

    x.bb();

     

    这就叫,只能在程序集中访问

     

    8个声明修饰符

      

       Partial:在整个同一程序集中定义分部类和结构,详解见问题1。

       Static: 声明属于类型本身而不是属于特定对象的成员。

       Abstract:抽象类,只能是其他类的基类。类中的方法只声明不实现,方法的实现在他的派生类中完成。

       Sealed:指定类不能被继承。

       Virtual:用于修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象

    Override:提供从基类继承的成员的新实现

    New:作修饰符,隐藏从基类成员继承的成员,在不使用 new 修饰符的情况下隐藏成员是允许的,但会生成警告。作运算符,用于创建对象和调用构造函数。

       Extern:用于声明在外部实现的方法。 extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 特性一起使用。 在这种情况下,还必须将方法声明为 static

       Virtual,override和new 的区别

    1.       virtual和override配套使用。在基类base中声明了虚方法method()并用virtual修饰,在子类derived中重写方法method()并用override修饰。那么当将子类的实例赋予基类的对象(不需要强制转换)时即Base Bclass= new Derived();Bclass.Method()是调用了子类的method()方法,而不是基类的。所以

    2.       new不需要和virtual配套使用。在基类base中声明了方法method(),在子类derived中声明了同名的方法method()并用new修饰。那么当将子类的实例赋予基类的对象时即Base Bclass= new Derived();Bclass.Method()是调用了基类类的method()方法,而不是子类的。

    3.       这说明,override可以覆盖基类的方法,让基类的方法以子类的内容实现,而new不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已.

     

    下面,我以例子来说明他们之间的微妙区别:

    public class GrandClass//基类 {         public GrandClass()         {                 Console.WriteLine("In GrandClass.Constructor");         }         public virtual void Method()//用virtual才可以在子类中用override,而new不需要这样         {                 Console.WriteLine("In GrandClass.Method()");         } }
    public class ParentClass:GrandClass//继承基类,看看override状态 {         public ParentClass()         {                 Console.WriteLine("In ParentClass.Constructor");         }         public override void Method()//使用override,是说把基类的方法重新定义         {                 Console.WriteLine("In ParentClass.Method() use override");         } }
    public class NewParentClass:GrandClass//继承基类,看看new状态 {         public NewParentClass()         {                 Console.WriteLine("In NewParentClass.Constructor");         }         new public void Method()//使用new,不是说用到基类的方法,而是重新定义一个子类方法,只不过,方法名称与基类相同         {                 Console.WriteLine("In NewParentClass.Method()");         } }

      下面的调用代码:

    static void Main()  {         GrandClass Parent=(GrandClass)new ParentClass();//用override子类加框一个基类对象句柄         Parent.Method();         GrandClass NewParent=(GrandClass)new NewParentClass();//用new子类加框一个基类对象句柄         NewParent.Method();         NewParentClass NewParent1=new NewParentClass();//一个子类句柄         NewParent1.Method(); }

      结果是这样的:

    [1]In GrandClass.Constructor [2]In ParentClass.Constructor [3]In ParentClass.Method() use override [4]In GrandClass.Constructor [5]In NewParentClass.Constructor [6]In GrandClass.Method() [7]In GrandClass.Constructor [8]In NewParentClass.Constructor [9]In NewParentClass.Method()

      结果前的序号是我自己加的.为了以下的分析:   [1],[2]两句是GrandClass Parent=(GrandClass)new ParentClass();的结果.(注意一下子类构建器与基类构建器的初始化顺序)   [3]是Parent.Method();结果.   [4],[5]两句是GrandClass NewParent=(GrandClass)new NewParentClass();的结果.   [6]是NewParent.Method();的结果.   [7],[8]两句是GrandClass NewParent1=(GrandClass)new NewParentClass();的结果.   [9]是NewParent1.Method();的结果.
      这里我们可以看到,同样是用子类的对象构造一个基类句柄.结果却很明显,可以看到[3]和[6]的区别.[3]调用了子类的Method(),而[6]调用了基类的Method().   这说明,override可以覆盖基类的方法,让基类的方法以子类的内容实现,而new不用来覆盖基类的方法,而是全新定义一个子类的方法,这个方法只属于子类,与基类的方法无关,只是名字上相同而已.      而这一例子的基础是建立在用子类对象加框成基类对象的,目的是实现用基类句柄调用子类方法,以实现重载的多态性.   如果想调用子类的new方法,用子类的句柄(绝对不能用基类句柄)来调用.结果[9]可以看出来.   用new是在为子类定义方法名时,实在没有办法定义方法名的情况才与基类的方法相同,但这个方法只在子类中起到作用,而不影响基类的方法.也就是说,new方法就是子类新定义的方法.用override是直正意义上的重载. 

    注意:部分内容转载:

    本文由新葡亰496net发布于奥门新萄京娱乐场,转载请注明出处:新葡亰496net访问修饰符,中访问修饰符

    关键词:

上一篇:没有了

下一篇:没有了