.NET重新学习 1 关键字

一、base关键字

可以通过base关键字访问上一级父类方法的访问。静态static函数无法调用base

二、new 关键字new

new有2个作用。

new运算符   用来分配内存空间和初始化对象。

new修饰符   微软官方说明:可以显式隐藏从基类继承的成员,该成员的派生版本将替换基类版本。(以前一直不在乎这种场合,因为编译器就提示警告)他和overrider有什么区别呢?

   /// <summary>
    /// 关键字
    /// </summary>
    public class KeywordA
    {

        public KeywordA()
        {
            Name = "apple";
        }
        public string Name { get; set; } 

        public virtual void Test()
        {
            Console.WriteLine("KeywordA.Test()" + Name);
        }

        public   void Test1()
        {
            Console.WriteLine("KeywordA.Test1()" + Name);
        }
    }

    public class KeywordB : KeywordA
    {
        public KeywordB()
        {
            Name = "button";
        }
         public new  string Name { get; set; }
        public new  void Test()
        {
            Console.WriteLine("KeywordB.Test()" + Name);
            base.Test();
        }

        public new void Test1()
        {
            Console.WriteLine("KeywordB.Test1()" + Name);
            base.Test1();
        }
    }

    public class KeywordC : KeywordA
    {
        public KeywordC()
        {
            Name = "city";
        }

        public override void Test()
        {
            Console.WriteLine("KeywordC.Test()"+Name);
            base.Test();
        }
    }
        static void Main(string[] args)
        {
            KeywordA a = new KeywordA();
            a.Test();
            a.Test1();
            Console.WriteLine("=========================");
            KeywordB b = new KeywordB();
            b.Test();
            b.Test1();
            a = new KeywordB();
            a.Test();
            a.Test1();
            Console.WriteLine("=========================");
            KeywordC c = new KeywordC();
            c.Test();

            a = new KeywordC();
            a.Test();
            a.Test1();
            Console.WriteLine("=========================");
            Console.ReadKey();
        }

通过以上代码执行得出以下结果:

KeywordA.Test()apple
KeywordA.Test1()apple
=========================
KeywordB.Test()button
KeywordA.Test()apple
KeywordB.Test1()button
KeywordA.Test1()apple
KeywordA.Test()apple
KeywordA.Test1()apple
=========================
KeywordC.Test()city
KeywordA.Test()city
KeywordC.Test()city
KeywordA.Test()city
KeywordA.Test1()city
=========================

1.new 只是个修饰符,看IL代码和不加NEW的方法一样。都叫覆盖。为了减少warn,建议加把。

2.虚方法、实方法都可以被覆盖(new),抽象方法,接口 不可以。

3.不管是重写还是覆盖都不会影响父类自身的功能。

4.当用子类创建父类的时候,如 A c = new B(),重写会调用子类的功能;而覆盖不会,仍然调用父类功能。

三、abstract 修饰符 abstract关键字

关于virtual 虚方法和抽象方法 、抽象类网上资料太多了。也非常好区分。abstract继承类必须实现抽象定义。而virtual 可以选择是否重写基类虚方法。 这里就摘录微软的定义了:

  • abstract 修饰符指示所修饰的内容缺少实现或未完全实现。
  • abstract 修饰符可用于类、方法、属性、索引器和事件。
  • 标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。

抽象类具有以下特性:

  • 抽象类不能实例化。
  • 抽象类可以包含抽象方法和抽象访问器。
  • 不能用 sealed(C# 参考) 修饰符修饰抽象类,因为这两个修饰符的含义是相反的。 采用 sealed 修饰符的类无法继承,而 abstract 修饰符要求对类进行继承。
  • 从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实际实现。

四、virtual 修饰符

virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。

除了声明和调用语法不同外,虚拟属性的行为与抽象方法一样。

  • 在静态属性上使用 virtual 修饰符是错误的。
  • 通过包括使用 override 修饰符的属性声明,可在派生类中重写虚拟继承属性。

五、const / readonly

都是只读的意思。表面上看区别在于const首次赋值后就不可以改了,而readonly在初始化类后就不能修改了。

    public class Keyword2
    {

        public static string Name_static = "Name_static";

        public readonly string Name_readonly = "Name_readonly";

        public const string Name_const = "Name_const";

        public static readonly string Name_static_readonly = "Name_static_readonly";

        public Keyword2(string text="Init")
        {
            Name_static = "Name_static_" + text;
            Name_readonly = "Name_readonly_" + text;
            //Name_const = "Name_const" + text;
            //Name_static_readonly = "Name_static_readonly" + text;

        }

    }
        static void Main(string[] args)
        {
            //DoKeyword1();
            DoKeyword2();

            Console.ReadKey();
        }

        /// <summary>
        /// const readonly
        /// </summary>
        private static void DoKeyword2()
        {
            Console.WriteLine("========初始化字段=================");
            Console.WriteLine(Keyword2.Name_const);
            Console.WriteLine(Keyword2.Name_static);
            Console.WriteLine(Keyword2.Name_static_readonly);

            Console.WriteLine("========初始化构造函数=================");
            Keyword2 kw = new Keyword2();
            Console.WriteLine(kw.Name_readonly);
            Console.WriteLine(Keyword2.Name_const);
            Console.WriteLine(Keyword2.Name_static);
            Console.WriteLine(Keyword2.Name_static_readonly);

            Console.WriteLine("========修改内容=================");
            //Keyword2.Name_const = Keyword2.Name_const+"_Edit";
            //Keyword2.Name_static_readonly = Keyword2.Name_static_readonly + "_Edit";
            //kw.Name_readonly = Keyword2.Name_readonly + "_Edit";
            Keyword2.Name_static = Keyword2.Name_static + "_Edit";
            Console.WriteLine(Keyword2.Name_static);
        }

IL代码:

.class public auto ansi beforefieldinit 关键字使用和执行顺序.Keyword2
    extends [mscorlib]System.Object
{
    // Fields
    .field public static literal string Name_const = "Name_const"
    .field public static string Name_static
    .field public initonly string Name_readonly
    .field public static initonly string Name_static_readonly

    // Methods
    .method public hidebysig specialname rtspecialname
        instance void .ctor (
            [opt] string text
        ) cil managed
    {
        .param [1] = "Init"
        // Method begins at RVA 0x2156
        // Code size 54 (0x36)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: ldstr "Name_readonly"
        IL_0006: stfld string 关键字使用和执行顺序.Keyword2::Name_readonly
        IL_000b: ldarg.0
        IL_000c: call instance void [mscorlib]System.Object::.ctor()
        IL_0011: nop
        IL_0012: nop
        IL_0013: ldstr "Name_static_"
        IL_0018: ldarg.1
        IL_0019: call string [mscorlib]System.String::Concat(string, string)
        IL_001e: stsfld string 关键字使用和执行顺序.Keyword2::Name_static
        IL_0023: ldarg.0
        IL_0024: ldstr "Name_readonly_"
        IL_0029: ldarg.1
        IL_002a: call string [mscorlib]System.String::Concat(string, string)
        IL_002f: stfld string 关键字使用和执行顺序.Keyword2::Name_readonly
        IL_0034: nop
        IL_0035: ret
    } // end of method Keyword2::.ctor

    .method private hidebysig specialname rtspecialname static
        void .cctor () cil managed
    {
        // Method begins at RVA 0x218d
        // Code size 21 (0x15)
        .maxstack 8

        IL_0000: ldstr "Name_static"
        IL_0005: stsfld string 关键字使用和执行顺序.Keyword2::Name_static
        IL_000a: ldstr "Name_static_readonly"
        IL_000f: stsfld string 关键字使用和执行顺序.Keyword2::Name_static_readonly
        IL_0014: ret
    } // end of method Keyword2::.cctor

} // end of class 关键字使用和执行顺序.Keyword2

总结:

1.const 为啥不需要实例化知道了把。它也是静态的。

2.Name_readonly  在编译时自动将赋值写入构造函数,完成初始化值的。所以readonly的在构造函数内可修改。

3.初始化顺序是 先 const-> static ->构造函数。

六、volatile 修饰符

七、in/out 泛型修饰符

八、async 异步修饰符

时间: 2024-11-23 12:59:33

.NET重新学习 1 关键字的相关文章

swift学习之关键字inout

一般参数仅仅是在函数内可以改变的,当这个函数执行完后变量就会被销毁,不会有机会改变函数以外的变量,那么我们就会产生一个疑问,我们可不可以通过一个函数改变函数外面变量的值呢?答案是肯定的,这时我们就需要用到inout关键字了 声明函数时,在参数前面用inout修饰,在函数内部实现改变外部参数,注意,这里只能传入变量,不能传入常量和字面量,因为这些是不能变的一旦定义,当我们传入的时候,在变量名字前面用&符号修饰表示,传递给inout参数,表明这个变量在参数内部是可以被改变的 注意:inout修饰的参

学习java关键字

背景 由于在阿里的实习面试中被问到java有哪些关键字这个问题,但是自己感觉很基础却又一直没怎么关注的知识点,也许面试官不是要的你真正的能记住java的50个关键字,而是回答的思路,当时没想明白,只说了一些基本数据类型,现在好好总结一下. 分类 数据类型(8个) 关键字 类型 字长 备注 boolean 布尔型 1byte true,false byte 字节型 1byte -128~127 char 字符型 2byte Unicode码 short 短整型 2byte int 整型 4byte

[python 函数学习篇] 关键字参数

函数可以通过 关键字参数 的形式来调用,形如 keyword = value .例如,以下的函数: def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'): print "-- This parrot wouldn't", action, print "if you put", voltage, "volts through it." print &qu

C++入门学习——explicit关键字的作用

C++ 语言可以定义如何将其他类型的对象隐式转换为我们的类类型, 或将我们的类类型的对象隐式转换为其他类型. 下面为类类型的隐式转换的示例代码: #include <iostream> using namespace std; class A { public: A(int temp) //普通构造函数 { a = temp; cout << "普通构造函数: a= " << a << endl; } A(const A &tem

ES6学习之关键字

前言:什么是ES6?ECMAScript 6(简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.其中相比较于ES5新增了诸多的特性,并且ES6可转换为ES5的语法.->在线ES6转换为ES5工具. 本系列学习随笔参考了阮一峰老师的<ES6标准入门>. 一.let关键字 1.解决变量提升现象 我们在js中定义变量时,用var声明会出现这种情况: console.log(a); //不会报错,输出为undefined var a=1; 这就是js的变量提升现

Bootstrap 学习

说明:案例源自慕课网的学习. 关键字:响应式布局.class.component! 什么是响应式布局? 这就得从移动大军崛起之后说起,本来只为PC端浏览器设计的网站在移动端的体验太过恶劣.而且,因为移动端尺寸五花八门,如何适配移动端的浏览器成了一个难题. 好在有了css3-media query,这里不解释它是什么(其实我也不知道),举个例子就明白了. 要求:当浏览器的宽度小于800px的时候,背景色设为红色:其他时候设为蓝色. 实现: link.css body { background: r

javase学习笔记]-7.7 this之细节与应用

这一节我们接着上一节来继续学习this关键字. 我们之前在7.5节中的构造函数应注意的细节中提到过一个细节就是构造函数可以调用一般函数,但一般函数不能直接调用构造函数.但是我们没有深究构造函数能不能调用构造函数,那么现在我们就来看一看这个问题. 那么构造函数与构造函数之间是怎么访问呢? 为了掌握这个问题,我们必须要明确一个概念,那就是在一个类中的成员如果要被执行,就必须由对象调用.而每个对象都有一个所属的this. java语言给了关键字this这个功能,那就是用this调用构造函数,而且也是通

Java synchronized关键字用法(清晰易懂)

本篇随笔主要介绍 java 中 synchronized 关键字常用法,主要有以下四个方面: 1.实例方法同步 2.静态方法同步 3.实例方法中同步块 4.静态方法中同步块 我觉得在学习synchronized关键字之前,我们首先需要知道以下一点:Java 中每个实例对象对应一把锁且每个实例对象只有一把锁,synchronized 关键字是通过对相应的实例对象加锁来实现同步功能的. 一.实例方法中使用 synchronized 加锁 实例方法中默认被加锁的对象是调用此方法的实例对象. 1 cla

java注释、关键字与标识符

通常我们需要在源代码中添加文字用来对进行代码解释说明,但这些文字并不是Java代码的语法,会导致编译出错.这时我们可以使用注释来完成这一事项! 在编译时,编译器会忽略注释的存在,就好像注释内容不存在一样.所以注释并不会导致编译出错,同时注释还方便编写者和其他人阅读源代码,加强对代码的理解. Java中提供了三种注释方式,分别是: 1 单行注释 //注释内容 2 多行注释 /*注释内容*/ 3 文档注释 /**注释内容*/ 其中文档注释与多行注释作用基本相同,唯一的区别是文档注释可以使用javad