C# 的语法基础
发布日期:2021-05-04 20:59:06 浏览次数:16 分类:技术文章

本文共 6014 字,大约阅读时间需要 20 分钟。

文章目录


1.int与int?

int? , 表示可空类型,即是值可以为null

int i = default(int);//默认值为0 int? j = default(int?);//默认值为null

Null 与任何运算符运算都是null

j = null;int? k = j + 5;//k值为null

2.文本的输出

  • 只有整条语句带分号,块是不带分号的。
  • 直接使用:来指定数据的样式
static void Main(string[] args)        {
Console.WriteLine("Hello World!");// 语句后边带分号 Console.WriteLine($"{3000:C}"); Console.WriteLine($"{0,2}",600); // 指定同上边第二位对齐 Console.WriteLine($"{0:C}", 600); }// 块后面不带分号

数据样式:

  • c:货币
  • d:十进制
  • f:浮点
  • P: 百分比
  • e:科学记数法

3.类

类包括数据成员和函数成员

与类平级的预定义类型

  • 结构
  • 枚举
  • 数组
  • 委托
  • 接口

C # 与C++ 等有所不同,C# 没有全局变量的概念,即函数不能再类外声明,同样的,C#中也没有默认的返回类型,必须是指定的返回类型或者 void。


3.1类的实例

类的声明,是用来构建类的蓝图,一旦被声明,即可构建类的实例。既然要实例化一个类,就要用类的引用和实际数据都申请内存。

NewClass A = new NewClass();

实例化一个类,就要分配一个空间,分配空间,就要用new关键字,而且后边要跟()


3.2类的访问修饰符

在类的内部,任何成员之间都可以相互访问。

  • private:(不带访问符号,默认就是私有成员) 只能他自己的类访问
  • public:
  • protected:允许自己和派生类可以访问
  • internal:程序集内部可见
  • protected internal:派生类 程序集内部可见

3.3方法的参数类型

参数类型 修饰符 执行
系统把形参的值复制给实参
引用 ref 形参是实参的别名
输出 out 仅包含一个返回的值,形参是实参的别名
数组 params 允许传递可变数目的实参到方法

引用参数

public int Add(ref int a, ref int b)

输出参数

void Method (out int a)
static void Main(string[] args)        {
int sum; Add(out sum, 5, 8); Console.WriteLine(sum); } public static void Add(out int c, int a, int b) {
c = a + b; }

与引用参数不同,输出参数有以下要求:

  • 输出参数在被读取之前,必须先被赋值。
  • 在方法返回之前,方法内部任何可能路径,都必须为所有输出参数赋值一次。

数组参数

“数组参数”和数组是两码事,注意区分

  • 一个参数列表里,只能有一个数组参数,而且必须放在最后
  • 数组参数的所有参数都必须有相同的类型

声明方法如下:

void Method(int a,params int[] mm)

3.4命名参数

上边看到的都是位置参数,也就是说每个形参的位置都应该和实参的位置一一对应,除此之外,还可以使用命名参数,这样就可以任意顺序调用参数了。

Method(a: 3, b: 6, c: 3);

3.5可选参数

即给参数提供默认值

void Method(int a,int b=3){
}

如果这几种参数都存在的话,他们的声明的顺序之间的关系,如下图:

在这里插入图片描述

4.对象初始化语句

即在 new 对象的时候,就对里面的一些属性和字段赋值

注意写法

class ClassA    {
public int A {
get; set; } public int B {
get; set; } } // 对象初始化语句 ClassA classA = new ClassA () {
A = 9, B = 3; }// 如果选择使用没有参数的构造函数,后面的()可以直接不写。 ClassA classA = new ClassA {
A = 9, B = 3; }

对比实例构造函数的方法的声明方式,注意区分

class ClassA    {
public int Id {
get; set; } public string Name {
get; set; } public ClassA(int id) {
Id = id; } } ClassA classA = new ClassA(3);

5.类和继承

6.1 屏蔽基类的成员

派生类不能删除他继承的任何成员,但是可以用与其基类名称相同的成员来屏蔽基类成员。(此时,要让编译器知道你在故意屏蔽继承的成员,所以要用 new 修饰符,否则编译器会弹出警告。)

class SomeClass {
public string str {
get; set; } } class OtherClass : SomeClass {
new public string str {
get; set; } }

6.2 关于继承需要注意的点:

  • 除了特殊的 object 类,所有的类都是派生类,即使他们没有基类规格说明,类 object 是唯一的非派生类。
  • 虽然类只能继承一个基类,但是继承的层次没有限制。

6.3 基类的访问

如果基类必须要完整的访问被隐藏的基类,可以可以使用 基类访问表达式 访问隐藏的基类

基类的表达式是由关键字 base 后边跟一个点和成员的名字组成。

class SomeClass {
public string str = "SomeClass 类"; public void Method1(string value) {
Console.WriteLine($"SomeClass 中的 {value}"); } } class OtherClass : SomeClass {
new public string str = "OtherClass"; public void Method2(string value) {
Console.WriteLine($"OtherClass中的 {base.str}"); } }

如果你代码中,经常使用这个特性(即访问隐藏的继承类),那么你可能要重新评估类的设计了,一般来说,都是在没有其他办法的时候,使用这个特征。


6.4 使用基类的引用

class Program    {
static void Main(string[] args) {
OtherClass otherClass = new OtherClass(); SomeClass someClass = (OtherClass)otherClass; someClass.Print(); otherClass.Print(); } } class SomeClass {
public void Print() {
Console.WriteLine("这是基类"); } } class OtherClass : SomeClass {
new public void Print() {
Console.WriteLine("这是派生类"); } } 输出: 这是基类 这是派生类

6.5 虚方法和覆写方法

上边无论是 base 还是 强制类型转换 ,都是使用子类调用父类的方法,如果想用父类调用子类的方法,就要用到 虚方法

class Program    {
static void Main(string[] args) {
OtherClass otherClass = new OtherClass(); SomeClass someClass = (OtherClass)otherClass; someClass.Print(); otherClass.Print(); } } class SomeClass {
virtual public void Print() {
Console.WriteLine("这是基类"); } } class OtherClass : SomeClass {
override public void Print() {
Console.WriteLine("这是派生类"); } } 输出: 这是派生类 这是派生类

注意:

  • 覆写和被覆写的方法,都必须有相同的可访问性,不能被覆写的是 private ,而覆写的是 public
  • 不能覆写 static 和非虚方法。
  • 这种方法,只能在类型转换过程中,才能使用,直接引用无效。

6.6 继承中构造函数的使用

  • 要创建对象的基类部分,需要隐式调用基类的某个构造函数做为创建实例的一部分。
  • 继承层次链中,每个类在执行自己的构造函数体之前,都要执行他基类的构造函数。

创建一个实例的过程如下:

在这里插入图片描述

class SomeClass    {
virtual public void Print() {
Console.WriteLine("这是基类"); } } class OtherClass : SomeClass {
int MyFiled1 = 5; // 成员初始化 int MyFiled2; public OtherClass() // 构造函数执行,调用基类的无参构造函数 SomeClass() {
} override public void Print() {
Console.WriteLine("这是派生类"); } }

默认情况下,在构造对象的时候,会调用基类无参数的构造函数,但是构造函数可以重载,有可能有多个构造参数,所以如果派生类使用一个指定的基类构造函数,就要在构造函数初始化语句 中使用他。

有两种形式:

  • 使用关键字 base 并指明使用哪一个基类构造函数。
  • 使用关键字 this 指明应该使用当前类的哪一个构造函数。

base的用法:

class SomeClass    {
public string someClassString; public SomeClass() // 这个无参的构造函数不能省 {
} public SomeClass(string a) {
someClassString = a; } } class OtherClass : SomeClass {
int MyFiled1 = 5; // 成员初始化 int MyFiled2; public OtherClass(string a ):base(a) // 把构造函数,从子类传到父类。 {
} }

6.7 抽象成员

抽象成员是指被设计为要被覆写的函数成员。他具有以下特征

  • 必须是一个函数成员。字段和常量不行。
  • 必须要用 abstract 修饰符。
  • 不能有实现的代码块。
  • 抽象成员只能在抽下类中声明。
abstract public void PrintStuff(string s);

虚成员和抽象成员的比较

虚成员 抽象成员
关键字 virtual abstract
实现体 实现体 没有实现体
在派生类中覆写 能被覆写,使用 override 必须被覆写,使用 override
成员的类型 属性,事件,方法 ,索引器 属性,事件,方法 ,索引器

6.8 抽象类

抽象类是指定被继承的类。抽象类只能做其他类的基类

  • 就是用来被继承的(只能用作其他类的基类)
  • 不能被实例化

6.8 密封类

上边讲,抽象类必须用作基类,不能被实例化,而密封类恰恰与他相反。

  • 密封类只能用作独立的类,不能用作基类
  • 密封类使用 sealed 修饰符

6.this 关键字

  • this 关键字在类中使用,是对当前实例的引用。
  • 静态成员显然不是实例的一部分,所以不能再任何静态函数成员的代码中,使用 this 关键字

参考文献

[1]

上一篇:前端のHTML
下一篇:.net core 中使用 EFcore做ORM

发表评论

最新留言

很好
[***.229.124.182]2025年04月04日 23时48分30秒