.NET Core CSharp初级篇 1-4

本节内容为this、索引器、静态、常量以及只读

简介

在之前的课程中,我们谈论过了静态函数和字段的一小部分知识,本节内容中,我们将详细的讲解关于对象操作的例子,以及更加深入的解释面向对象。

常量

常量,顾名思义,就是一直为同一个值的变量,并且值不可以被改变。在C#中,定义一个常量需要使用const关键字声明。常量并不占用内存的空间。在C#程序编译的时候,编译器会把任何使用了该常量替换成这个值。

因为常量并不存储在内存中,因此常量只允许使用内置的数值类型,例如:bool、char、string、enum。并且声明的同时必须对常量进行初始化。

例如我们应用的版本号,通常在应用编译完成之后都是以一个常量存在,也不需要对他进行操作。看下列代码。

public const string Version="v2.1.1"

public string getString(string msg)
{
return "Copyright@2019" + msg + Version;
}

上述函数代码在编译时,将会变成:

public string getString(string msg)
{
return "Copyright@2019" + msg + "V2.1.1";
}

因为常量的上述特性,如果Y程序集使用了X程序集中的这个Version常量,如果X修改了该常量为“2.1.2”并重新编译,若Y不重新编译,Y中常量还是“2.1.1”,因为该常量会被直接固化于Y中并用常量值替换变量名。因此需要y进行重新编译才会使用新的常量值。

静态

静态是一个很常用的语法,我们可以在类中构造各种静态成员,例如静态字段、函数等等。再C#中定义静态成员的方法是使用修饰符static,调用的时候只需要使用“类名.成员名”。

在之前的课程中,我顺带提过一次,静态是一个只初始化执行一次,属于全体共有的一个东西,也可以说是该静态成员属于类本体所有,而不是每一个对象所有。我们就从静态构造函数、静态字段、静态函数这三块进行一个详细的讲解。

静态构造函数

我们之前以及对构造函数进行过一个简单的介绍,构造函数是在类被初始化(实例化)的时候调用,并且每创建一个对象就会调用一次构造函数。

而静态构造函数是每一个类型执行一次,也就是这个类型的所有对象公用一个静态构造函数。这区别与普通构造函数的一个对象执行一次。并且对于静态构造函数而言,一个类只允许有一个静态构造函数,并且必须无参。

静态构造函数在你访问一个类型的静态成员的时候,或者实例化一个类型的时候,编译器会自动的调用静态构造函数。

特别的,因为该初始化的构造函数(静态构造函数)属于所有变量共有并且会调用,那么假设该构造函数报错,那么这个类将再程序剩余生命周期内无法再被使用。

静态字段

静态字段也是一样,属于一切成员公有,在任何地方你都可以不实例化类的情况下对静态字段操作。

对于静态字段的初始化,分为两种情况:

  • 假定类存在一个静态构造函数,那么静态字段在静态构造函数被调用的一瞬间就会初始化;
  • 假定不存在静态构造函数,那么静态字段将会被类型被使用之前的一瞬间初始化(最晚执行),或者更早,在运行时的某一时间(并无法确定)被初始化。

静态字段初始化的顺序则与定义时的顺序一致,例如:

class A
{
public static int X = Y;
public static int Y = 15;
}
.....
Console.WriteLine("X:{0},Y:{1}",X,Y)

上例中,X,Y的初始化顺序是X先被初始化,此时Y没有初始化,则是0,因此输出是X:0,Y:15。

静态函数

与之前一样,静态函数可以在不实例化类的情况下调用,但是注意,在静态函数中,不允许使用任何非静态的字段。调用的时候直接使用类名.函数名()即可。

静态类

如果一个类,被声明为静态类,那么该类不可以被实例化,也不可以被继承,同时不可以包含非静态成员。非静态类中,可以包含静态成员。

只读

只读用于字段的访问控制,使用readonly关键字,通常情况下也可以使用无set访问器的属性进行实现。

class A
{
public string test{get;}
public readonly string _test;
}

静态成员的生命周期

从程序开始初始化到程序结束,因此滥用静态会导致性能问题。

this关键字

在C#中,this关键字表示操作的当前对象,在类里面,如果你使用this关键字,则this指代的是你每次操作对象时的当前对象。特别的,如果你的函数形参名称和字段名相同,并且你需要同时操作这个两个变量,那么你需要使用this关键字去指明你的操作对象,例如:

class A
{
private string data;
public string Data{get{return data;}} public void SetData(string data)
{
//this.data表示是当前对象的字段data
this.data = data;
} }

索引器

在之前的数组操作中,相信大家都发现了数组的访问通过了一个中括号和下标的方式进行访问,这个东西我们称为索引器。但是在类中的索引器可以以任何类型作为索引的key,这使得整个类的拓展性变得很好。

如何去定义一个索引器呢?这里就需要用到我们的this关键字了。定义的方式有点类似我们对于属性的定义

public class A
{
public double[] arry{get;set;}
public double this [int index]
{
get
{
return arry[index];
}
set
{
arry[index] = value;
}
}
}

通过索引器,我们可以自己定义各种不同的索引方式,而不用拘泥于下标访问

习题

1.请问下列代码输出什么?为什么?

class A
{
public static A a = new A();
public static int X = 3();
A()
{
Console.WriteLine(X);
}
}
class Program
{
static void Main()
{
Console.WriteLine(A.X);
}
}

2.试着使用索引器,写出一个二维数组的索引访问,要求实现倒序访问(即a[0]访问最后一位)

前往Github获取更多本节资料(PPT,实例代码)

如果我的教程帮到了您,希望您动动小手,在GitHub给我一个star

Github

BiliBili主页

WarrenRyan's Blog

博客园

CSharp初级篇 1-4 this、索引器、静态、常量以及只读的更多相关文章

  1. .NET Core CSharp初级篇 1-8泛型、逆变与协变

    .NET Core CSharp初级篇 1-8 本节内容为泛型 为什么需要泛型 泛型是一个非常有趣的东西,他的出现对于减少代码复用率有了很大的帮助.比如说遇到两个模块的功能非常相似,只是一个是处理in ...

  2. .NET Core CSharp初级篇 1-1

    .NET Core CSharp初级篇 1-1 本节内容是对于C#基础类型的存储方式以及C#基础类型的理论介绍 基础数据类型介绍 例如以下这句话:"张三是一名程序员,今年15岁重50.3kg ...

  3. NET Core CSharp初级篇 1-3面向对象

    .NET Core CSharp初级篇 1-3 本节内容为面向对象初级教程 类 简介 面向对象是整个C#中最核心最有特色的一个模块了,它很好的诠释了程序与现实世界的联系. 面向对象的三大特征:继承.多 ...

  4. .NET Core CSharp初级篇 类的生命历程

    .NET Core CSharp初级篇 1-7 本节内容为类的生命周期 引言 对象究竟是一个什么东西?对于许多初学者而言,对象都是一个非常抽象的知识点.如果非要用一句话描述,我觉得"万物皆对 ...

  5. .NET Core CSharp初级篇 1-5 接口、枚举、抽象

    .NET Core CSharp初级篇 1-5 本节内容类的接口.枚举.抽象 简介 问题 如果你需要表示星期或者是某些状态,使用字符串或者数字是否不直观? 你是否发现,无论何种电脑,它的USB口的设计 ...

  6. .NET Core CSharp初级篇 1-6 类的多态与继承

    .NET Core CSharp初级篇 1-6 本节内容为类的多态与继承 简介 终于讲到了面向对象三大特性中的两大特性--继承与多态.通过继承与多态,我们能很好的将类的拓展性发挥到了极致.在下面的内容 ...

  7. .NET Core CSharp初级篇 1-2 循环与判断

    .NET Core CSharp初级篇 1-2 本节内容循环与判断 循环 循环是一个在任何语言都是极为重要的语法,它可以用于很多东西,例如迭代数组等等.在C#中,语法层面的循环有:for , fore ...

  8. Kotlin——初级篇(二):变量、常量、注释

    在Kotlin中的变量.常量以及注释多多少少和Java语言是有着不同之处的.不管是变量.常量的定义方式,还是注释的使用.下面详细的介绍Kotlin中的变量.常量.注释的使用.以及和Java的对比. 如 ...

  9. C# 索引器的理解和使用

    概述 此部分内容引用自MSDN文档 使用索引器可以用类似于数组的方式为对象建立索引. get 取值函数返回值. set 取值函数分配值. this 关键字用于定义索引器. value 关键字用于定义 ...

随机推荐

  1. Android零基础入门第52节:自定义酷炫进度条

    原文:Android零基础入门第52节:自定义酷炫进度条 Android系统默认的ProgressBar往往都不能满足实际开发需要,一般都会开发者自定义ProgressBar. 在Android开发中 ...

  2. 赵海军获任中芯国际CEO 邱慈云留任副董事长、非执行董事(年薪40万美元+300万股票的认购权)

    集微网消息,中芯国际今日宣布,由赵海军博士接替邱慈云博士担任中芯国际首席执行官,邱慈云博士将留任副董事长.非执行董事,并于2017年6月30日前担任公司全职顾问,于当日生效.邱博士将与赵博士紧密合作, ...

  3. Oracle序列使用:建立、删除、使用

    Oracle序列使用:建立.删除 在开始讲解Oracle序列使用方法之前,先加一点关于Oracle client sqlplus的使用,就是如果执行多行语句的话一定要加“/”才能表示结束,并执行!本篇 ...

  4. DataSet与JSON互转

    DataSetConverter4Delphi https://github.com/ezequieljuliano/DataSetConverter4Delphi ----------------- ...

  5. Qt5---ftp上传功能(可直接克隆某个小模块,查看QT下FTP的socket原理)

    http://blog.csdn.net/freeape/article/details/52802163

  6. myeclipse2018的下载安装教程

    首先注意事项!!!!!!! 在安装破解前是不可以打开软件的 jdk版本不能是10版本,1.8或1.9都可以 附上MyEclipse2018的百度云下载链接: 链接:https://pan.baidu. ...

  7. JavaWEB路径总结

    这篇文章是小编一直想写的一篇,主要是对web阶段中各个路径进行的一些总结,希望读者看过之后对于路径方面有一个清晰的认识.首先声明一点:世界上一切东西都是相对的,对于这点而言,相信大家并不陌生,从初中开 ...

  8. Ubuntu 16.04.3启动MySQL报错

    今天安装mysql,连接MySQL时报错mysql: [Warning] Using a password on the command line interface can be insecure. ...

  9. SQL Server温故系列(3):SQL 子查询 & 公用表表达式 CTE

    1.子查询 Subqueries 1.1.单行子查询 1.2.多行子查询 1.3.相关子查询 1.4.嵌套子查询 1.5.子查询小结及性能问题 2.公用表表达式 CTE 2.1.普通公用表表达式 2. ...

  10. [Vue 牛刀小试]:第十五章 - 传统开发模式下的 axios 使用入门

    一.前言 在没有接触 React.Angular.Vue 这类 MVVM 的前端框架之前,无法抛弃 Jquery 的重要理由,除了优秀的前端 DOM 元素操作性以外,能够非常便捷的发起 http 请求 ...