C#基础语法要点总结学习笔记

——
声明:本文内容整理自菜鸟教程、微软文档,内容有改动。
https://www.runoob.com/csharp/csharp-tutorial.html 菜鸟教程
https://docs.microsoft.com/zh-cn/dotnet/csharp/ Microsoft 微软C#文档
零散的资料在每章节末尾给出。

1 C#简介

1.1基本概念

C# (读作“See Sharp”)是一个**面向对象(Object Oriented)**的编程语言,且进一步支持面向组件(Component Oriented)的编程。C# 基于 C 和 C++ 编写,因而存在相似的语法风格,但更接近于java,由微软(Microsoft)开发。C# 采用统一的类型系统,所有 C# 类型(包括 int 和 double 等基元类型)均继承自一个根 object 类型。 因此,所有类型共用一组通用运算,任何类型的值都可以一致地进行存储、传输和处理。 此外,C# 还支持用户定义的引用类型和值类型,从而支持对象动态分配以及轻量级结构的内嵌式存储。

C# 是 .Net 框架(.Net Framework)的一部分。使用相应的编译器编译C#编写的代码时,无法获得机器代码, 而是获得中间语言( IL)代码。托管代码(Managed Code)是一种中间语言,是执行过程交由运行时管理的代码,在这种情况下,相关的运行时称为公共语言运行时 (CLR)。CLR 负责提取托管代码、将其编译成机器代码,然后执行它。运行时提供多个重要服务,例如自动内存管理、安全边界、类型安全,等等。

1.2程序结构

一个 C# 程序主要包括以下部分:

  1. using System:在任何 C# 程序中皆为第一条语句。using 关键字用于在程序中包含命名空间,一个程序可以包含多个 using 语句;
  2. namespace( 命名空间)声明:一个 namespace 里包含了一系列的类(class)。命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方式,在一个命名空间中声明的类的名称可以与另一个命名空间中声明的类的名称相同。命名空间可以被嵌套。
  3. class声明:用于声明一个类。类是具有相同属性和服务的一组对象的集合。定义类意味着类的对象由什么组成及在这个对象上可执行什么操作。类一般包含多个方法(method),方法定义了类的行为。
    4. Main 方法:是所有 C# 程序的 入口点。Main 方法说明当执行时类将做什么动作。
  4. 语句(Statements)& 表达式(Expressions)
    6. 注释:多行注释:/* */;单行注释是用 ‘//’ 符号表示。
using System;
namespace HelloWorldApplication
{
   class HelloWorld
   {
      static void Main(string[] args)
      {
         /* 我的第一个 C# 程序*/
         Console.WriteLine("Hello World");
         Console.ReadKey();
      }
   }
}

2对象、类和实例

在面向对象的程序设计方法中,对象是对客观事物的抽象,而是对对象的抽象,为所有的对象定义了抽象的属性与行为;反过来说,类是对象是类的一个具体。类定义完毕后不能直接操作,这是因为类仍然是抽象的概念,需要通过实例化来创建类的具体对象,该具体对象被称之为实例

实际上以电气工程师视角带入进行理解会容易的多,工业现场早已存在许许多多的工艺对象,例如对驱动器对象(drive object),我们将其抽象为轴类(Axis Class),由于运动控制对象通常为多轴机构,因而将轴类实例化为X轴(Axis_X)、Y轴(Axis_Y)、Z轴(Axis_Z)…
在这里我实际上是在复述西门子PLC的组态轴操作,实际上工业上的面向对象技术已经十分成熟。
C#基础语法要点总结学习笔记_第1张图片

这里给出一个创建类并实例化的模板:

<access specifier> class  class_name//定义类
{
<access specifier> <data type> variable1;//定义成员变量
...
<access specifier> <return type> method1(parameter_list)//定义方法
    {
        // method body
    }
    ...
 }
 
 <access specifier> class  main_class_name	//带main方法的类
{
	 static void Main(string[] args)//main方法
      {
         class_name instance_name = new class_name();//类的实例化(创建对象):类 实例名 = new   类();
         instance_name.method1(parameter_list);//方法调用:实例名.方法名();
      }

3类的概念

3.1字段和属性

字段(Field)和 属性(Property) 都属于类的成员,是C#面向对象模式中的两个概念。

  • 字段:字段又称为成员变量,是在类中直接声明的任意类型的变量。字段在类的内部做数据交互使用,因而以private修饰,称为私有域;需要为外部提供数据时,需将字段封装成属性(而不是改为public修饰)。
  • 属性:属性是字段的扩展,用于为外部提供数据。属性本身并不保存任何数据,使用访问器(accessors)来读取、写入或计算私有域的值。属性的作用是:1.避免出现非法数据;2.限定属性为只读或只写;

访问器分为get访问器和set访问器,其语法格式见下:

private code	//字段
public string Code	//属性
{
   get{return code;}
   set{code = value;}
}

在.NET3.0及其后续版本中,可简写为自动属性,其语法见下:

private code {get;set};

3.2方法

方法类似C语言的函数,由局部变量和方法主体组成。一个方法是把一些相关的语句组织在一起,用来执行一个任务的语句块。每一个 C# 程序至少有一个带有 Main 方法的类。Main 方法是每个 C# 应用程序的入口点,并在启动程序时由公共语言运行时 (CLR) 调用。

要使用一个方法,需要定义方法并调用方法。

方法的定义模板见下:

<Access Specifier> <Return Type> <Method Name>(Parameter List)//访问修饰符;返回类型;方法名称;参数列表
{
	//局部变量
   Method Body//方法主体
} 

通过指定访问修饰符(如 public 或 private)、可选修饰符(如 abstract 或 sealed)、返回值、方法的名称以及任何方法参数,在类、结构或接口中声明方法。 这些部件一起构成方法签名。注意,出于方法重载的目的,方法的返回类型不是方法签名的一部分。 但是在确定委托和它所指向的方法之间的兼容性时,它是方法签名的一部分。

当调用带有参数的方法时,可按值传递按引用传递方法的参数。
按值传递参数:会为每个值参数创建一个新的存储位置。
按引用传递参数:与提供给方法的实际参数具有相同的内存位置;需使用ref关键字
按引用传递参数的案例程序见下:

 public void swap(ref int x, ref int y)
      {
      Method Body//方法主体
      }

3.3类的构造函数

每当创建类或结构时,将会调用其构造函数。构造函数是一种方法,其名称与其类型的名称相同,没有任何返回类型。构造函数主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。
构造函数默认存在,若未自定义构造函数,则系统调用默认构造函数;否则系统调用自定义构造函数。
默认的构造函数没有任何参数。带有参数的构造函数叫做参数化构造函数,可以在创建对象的同时给对象赋初始值。

class Chinar
    {
         //默认构造函数
        public Chinar() //声明构造函数,函数名与类名相同
        {
            Method Body	//构造函数主体
        }

        //参数化构造函数
        public Chinar(int a, int b, string c, object d)
        {
        	Method Body	//构造函数主体
        }
    }

3.4 抽象类

类分为抽象类具体类
抽象类是特殊的类,其用途是提供一个可供多个派生类共享的通用基类定义。抽象类同具体类的核心区别在于不能被实例化,抽象类必须被继承,才能被使用。
通过在类定义前面放置关键字 abstract,可以将类声明为抽象类。

在抽象类中可以定义抽象方法和抽象属性。

  • 抽象属性声明不提供属性访问器的实现,仅声明该类支持属性。
  • 抽象方法只有声明没有实现,所以方法定义后面是分号而不是常规的方法块。 抽象类的派生类必须实现所有抽象方法。
public abstract class A	//抽象类
{
	public abstract string Name { get; }	//抽象属性
    public abstract void DoWork(int i);	//抽象方法
}

注意抽象类也可以像具体类那样定义具体方法和具体属性。

注意抽象类和接口的区别,二者为配合而非替代关系。
抽象类除无法实例化外,其余功能同具体类一致。一个抽象类可以实现多个接口。

3.5静态类和静态成员

静态类与非静态类基本相同,其差异在于静态类无法被实例化,由于不存在任何实例变量,因此可以使用类名本身访问静态类的成员。静态类不能被继承或继承自任何类。静态类需要使用静态修饰符static声明。

类的成员分为静态成员和实例成员,静态成员包括方法、字段、属性或事件。 静态成员属于类,而实例成员则属于对象(类实例)。对于静态成员,无论创建多少个类实例,永远只有一个静态副本。静态成员需要使用静态修饰符static声明。

非静态类可以包含静态成员,静态类只包含静态成员。

4 C#面向对象的基本特征

面向对象的三个特征:封装、继承、多态。

4.1封装

封装(encapsulation)就是隐藏对象的属性和实现细节,通过 访问修饰符(Access Specifier) 来实现。
访问修饰符定义了类成员的范围和可见性。C# 支持的访问修饰符如下所示:
C#基础语法要点总结学习笔记_第2张图片

  • public:所有对象都可以访问;
  • private:对象本身在对象内部可以访问;
  • protected:只有该类对象及其子类对象可以访问
  • internal:同一个程序集的对象可以访问(被编译到同一个dll或exe中的程序就是处于同一个程序集中);
  • protected internal:访问限于当前程序集或派生自包含类的类型。

封装演示代码见下:

 public double length;

4.2继承

C#只支持单一继承。

继承(extend)是指当创建一个类时,程序员不需要完全重新编写新的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员,从而在无需重新编写原来的类的情况下对这些功能进行扩展。这个已有的类被称为基类,这个新的类被称为派生类(或子类)。子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法。继承的思想实现了**属于(IS-A)**关系。

class <派生类> : <基类>
 class Rectangle: Shape

继承仅适用于类和接口,其他各种类型(结构、委托和枚举)均不支持继承。
通过在类定义前面放置关键字 sealed,可以将类声明为密封类。当一个类被声明为 sealed 时,它不能被继承。

4.3多态

多态(Polymorphism)是指同一个接口,使用不同的实例而执行不同操作。在 C# 中,每个类型都是多态的,因为包括用户定义类型在内的所有类型都继承自 Object。

继承是子类可以调父类的方法,多态是父类可以调子类的方法。

重载(overload):在同一个作用域(一般指一个类)的两个或多个方法函数名相同,参数列表不同的方法叫做重载。
重写(overwrite):子类中为满足自己的需要来重复定义某个方法的不同实现,需要用 override 关键字,被重写的方法必须是虚方法,用的是 virtual 关键字。

5接口

**接口(interface)**是一种引用类型,定义了派生类应遵循的标准结构。
接口成员可以包含实例方法、属性、事件、索引器或这四种成员类型的任意组合。接口只包含成员声明而没有具体实现的代码(接口无法直接进行实例化),只在继承该接口的派生类里实现接口成员的定义。
接口使得实现接口的类或结构在形式上保持一致。

定义接口

interface IMyInterface//通常接口命令以大写 I 字母开头
{
    void MethodToImplement();//接口成员,此处声明了方法
}

实现接口

class InterfaceImplementer : IMyInterface//父类名在前,接口名在后,只能继承一个父类,可以实现多个
{
 ...
 }

6类型

6.1基本概念

C#类型分为值类型(Value types)和引用类型(Reference types)。 值类型的变量直接包含数据;引用类型的变量包含对类型实例的引用,即指向一个内存地址。

  1. 值类型: int、char、float… 值类型还可以是结构类型和枚举类型。
  2. 引用类型:在c#中所有的类都是引用类型,包括接口;内置的引用类型有:object、dynamic 和 string:
    ·对象(Object)类型:是 C#中所有数据类型的终极基类,可以被分配任何其他类型,但需要先进行类型转换。 当一个值类型转换为对象类型时,则被称为装箱;另一方面,当一个对象类型转换为值类型时,则被称为拆箱
    ·动态(Dynamic)类型
    ·字符串(String)类型:可以给变量分配任何字符串值。

值类型和引用类型的区别见下表。
C#基础语法要点总结学习笔记_第3张图片
适用场合

  1. 值类型在内存管理方面具有更好的效率,并且不支持多态,适合用做存储数据的载体;引用类型支持多态,适合用于定义应用程序的行为。
  2. 引用类型可以派生出新的类型,而值类型不能,因为所有的值类型都是密封的。
  3. 引用类型可包含null值,值类型不能(可空类型功能允许将null赋给值类型,如int a=null);
  4. 引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值。

C#引用类型和值类型的适用场合和区别

6.2值类型简述

可空类型

可空类型(Nullable)是一个特殊的数据类型,表示其基础值类型除了正常范围内的值还有一个 null 值,该基础值类型本身不能是可为空的值类型。在处理数据库和其他包含可能未赋值的元素的数据类型时,将 null 赋值给数值类型或布尔型的功能特别有用。

单问号 “?”用于对 int,double,bool 等无法直接赋值为 null 的数据类型进行 null 的赋值。

< data_type> ? <variable_name> = null;
int? i = null //例子

6.3引用类型简述

数组

c#的数组初始化风格同c语言不同,数组是一个引用类型,所以需要使用 new 关键字来创建数组的实例:

double[] balance = new double[10];	//声明
balance[0] = 4500.0;//赋值
//或
double[] balance = { 2340.0, 4523.69, 3421.0};
//也可以直接把声明和赋值连在一起
double[] balance = new double[10] { 99,  98, 92, 97, 95};//数组大小可省

字符串

尽管字符串为引用类型,基于其特性并不需要new,因此方法上更接近于值类型。

常用的几种方法:

string fname = "Rowan";
等同于
string fname = @"Rowan";	//用 @ 符号加在字符串前面表示其中的转义字符“不”被处理。

也可以使用字符数组来表示字符串。

char[] letters = { 'H', 'e', 'l', 'l','o' };

6.4值类型变量与引用类型变量赋值差异

两个值类型变量的赋值
值类型的变量直接包含数据,在赋值的时候只是把数据复制并赋给另一个变量。

 int var1=2;
 int var2=var1;	值类型变量var1变量值2直接复制给var2,var值为2

两个引用类型变量的赋值
引用类型的变量指向一个内存地址,在赋值的时候把该内存地址赋给另一个变量,因此2个引用变量中保存的是同一引用。

MyClass objectB=objectA;	//引用变量的赋值
objectA.val=10;	//给objectA.val赋值=10 由于objectB和objectA指向同一内存地址,所以ojbectB.val的值也为10
objectB.val=20;	//给objectB.val赋值=20 由于objectB和objectA指向同一内存地址,所以objectA.val的值也为20

C#值类型赋值与引用类型的赋值

6.5类型转换

C#是一门强类型语言。C#支持两种类型转换方式。

(1)隐式类型转换
C# 默认的以安全方式进行的转换, 不会导致数据丢失。

(2)显式类型转换
即强制类型转换,会造成数据丢失。强制转换需要强制转换运算符,形式为(T)E,将表达式 E 的结果显式转换为类型 T。

 double x = 1234.7;
        int a;
        // Cast double to int.
        a = (int)x;

注意值类型同string类型的转换无法通过强制转换运算符实现。
·值类型转string类型时,使用convert转换,例如:

 int number = 18;	//值类型
 string str = num ber.Tostring();	//转换为string类型

·string类型转值类型时,使用Parse转换,例如:

string strNumber = "18";
int num01 = int.Parse(strNumber);

你可能感兴趣的:(编程语言,c#,编程语言)