c#个人总结中级篇

本文介绍了C#编程的中级概念,包括调试技巧,异常处理,面向对象编程的核心概念,如类、构造函数、属性、匿名类型、堆和栈、值类型与引用类型,以及继承、虚方法、抽象类和接口的使用。同时讲解了列表、泛型和索引器的基本操作,以及Equals方法的用途。
摘要由CSDN通过智能技术生成

调试和错误处理

一、正常模式下的调试
1.在VS中使用Console.WriteLine()的方法向控制台输出变量的值,通过查看这个变量的值是否适合我们预期来调试错误。
2.在Unity中使用Debug.Log() 、Debug.LogError()、Debug.LogWar()向Unity console窗口输出信息帮助调试错误。

二、中断模式下的调试
指暂停程序执行,然后查看程序中的状态,也可以让程序继续执行。

断点:断点是源代码中自动进入中断模式的一个标记,当遇到断点的是很好程序会自己进入中断模式。
插入断点:①右键代码行,选择breakpoint(断点)->insert breakpoint(插入断点)。
②光标定位到代码行,选择菜单上的Debug(调试)->Toggle Breakpoint(切换断点)。
③光标定位到代码行,在此行按下F9,再按一次取消。(常用)
④在需要添加断的行首位置,直接单击,再次点击取消。(常用)
窗口BreakPoint:调试->窗口->断点

单步执行代码
在中断模式下我们可以单步执行代码,单步执行代码有两种:逐过程和逐语句,两者都是一条一条语句执行,区别在于逐过程遇到函数,不会进入函数内部,而是把函数当成一条语句执行。

异常处理

try catch finally

try{
   

}
catch(<ExceptionType> e){
   
	
}
finally{
   
}

其中catch块可以有0或多个,finally块可以有0或1个。但如果没有catch块,必须要有finally块,没有finally块必须要有catch块,catch块和finally块可以共存。
try:try块包含可能出现的异常代码(一条或多条语句)
catch:catch块用来捕捉异常,当代码发生异常,而且异常类型catch块中类型一样时,就会执行catch块,若catch块参数不写,则会发生任何异常都会执行的catch块。
finally:finally块中包含了始终执行代码,不管有无异常都会执行。

在try块中,如果有一行代码发生异常,那么try块中剩余的代码将不会执行。例如:

while(true)
{
   
	try{
   
		int num =Convert.ToInt32(Console.ReadLine());
		break;
	}
	cathc{
   
		Console.WriteLine("输入的不是整数 ");
	}
}

上述代码中如果输入的不是int类型的整数,将会无限继续循环用户输入,直到输入正确为止。证明了,try中第一行代码错误时,不会执行下一行的break代码。

面向对象编程

简单来说就是结构化编程,对程序中的变量结构划分,让编程更加清晰。

实际上是创建对象的模板。每个对象都包含数据,并提供数据处理和访问数据的方法。
类中的数据和函数称为成员。

class Vehicle
{
   
	public int speed;//数据成员
	public int maxSpeed;//这些数据成员叫做域,也叫字段
	public void Run()//函数成员
	
	{
   
		
	}
}

编程规范上,习惯把所有字段设成private,只可以在类内部访问,当其他类对象想要范文时,需要设置set方法进行访问。例如:

private x,y,z;
public void SetX(float x)
{
   
	this.x=x;
}

①如果我们直接在方法内部访问同名的变量的时候,优先访问最近的(形参)。
②我们可以通过this.表示访问的时类的字段或者方法。

构造函数

我们在构造对象的时候,对象的初始化过程是自动完成的,构造函数就是用于初始化的函数。

声明基本的构造函数的语法就是去声明一个和所在类同名的方法,但该方法没有返回类型。例如:

class MyClass
{
   
	public MyClass()
	{
   
		//构造函数的函数体
	}
}

当我们使用创建类或结构时,将会调用其构造函数,构造函数与该类或结构具有相同名称,并且通常初始化新对象的数据成员。当使用new运算符对该类进行实例化时,在为新对象分配内存后,new运算符会立即调用该类的构造函数。如:

public static void Main(string []args)
{
   
	MyClass mc = new MyClass();//立即调用构造函数
}

构造函数可以进行重载,跟普通函数的重载一样的规则。
不带任何参数的构造函数称为“无参数构造函数” 。 每当使用 new 运算符实例化对象且不为 new 提供任何参数时,会调用无参数构造函数。即上诉代码。
注意:当我们不写构造函数时,编译器会提供给我们一个默认的无参构造函数,但我们定义一个或者多个构造函数时,编译器就不会再提供默认构造函数。

属性的定义

public int MyIntProp
{
   
	get{
   //get code}
	set{
   //set code}
}

①定义属性需要名字和类型
②属性包含get块个set块
③访问属性和访问字段一样,当获取属性的值的时候,就会调用属性的get块,所以get块需要返回值,类型就是属性类型;当我们给属性设置值时,就会调用set块,可以在set块中通过value访问到我们设置的值。

官方文档:
属性结合了字段和方法的多个方面。 对于对象的用户来说,属性似乎是一个字段,访问属性需要相同的语法。 对于类的实现者来说,属性是一两个代码块,表示 get 访问器和/或 set 访问器。 读取属性时,执行 get 访问器的代码块;向属性赋予新值时,执行 set 访问器的代码块。 将不带 set 访问器的属性视为只读。 将不带 get 访问器的属性视为只写。 将具有以上两个访问器的属性视为读写。
与字段不同,属性不会被归类为变量。 因此,不能将属性作为 ref 或 out 参数传递。
属性具有许多用途:它们可以先验证数据,再允许进行更改;可以在类上透明地公开数据,其中数据实际是从某个其他源(如数据库)检索到的;可以在数据发生更改时采取措施,例如引发事件或更改其他字段的值。

简而言之就是属性的get块和set块就是读和写的功能,get块会返回值,set块中始终有一个名为value的参数,value可以理解为外部设置值时候传递的参数。例如:

private int age;
public int Age
{
   
	set
	{
   
			if(value < 0)
			{
   
				return ;
			}
			age = value;					
	}
	get
	{
   
		return age;
	}
}

自动实现属性

private string name;
public string Name
{
   
	get{
   return name;}
	set{
   name = value;}
}

等价于:

public string Name{
   get;set;}

编译器会自动给我们提供一个字段来存储name。

public static void Main(string [] args)
{
   
	\\假设属性定义在Vector类上
	Vector v3 =new Vector();
	v3.Name = "CHAI";
	Console.WriteLine(v3.Name);
}

输出结果为CHAI。

匿名类型

在创建变量(对象的时候)必须指定类型,其实也可以不指定类型,这个就是匿名类型,例:

var v1 = 1000;

当匿名类型被赋值时,其类型就会被确定下来,即上述代码时int类型。

堆和栈

程序运行时的内存区域

我们把内存空间分为堆空间和栈空间。栈空间小,读取速度快,堆空间比较大,读取速度慢。
:数据只能从栈顶插入和删除,把数据插入栈顶叫做入栈(push),把数从栈顶删除叫出栈(pop)。

:是一块内存区域,与栈不同,堆里内存能够任意顺序存入和移除。

值类型和引用类型

值类型(整数,bool,char,小数,struct)值类型数据放在栈中。值类型数据放在栈中。
引用类型(string ,数值,定义的类,内置的类)。引用类型数据放在堆里,引用存放在栈中。
引用类型的赋值:当我们使用引用类型赋值时,其实时赋值引用类的引用。
注:如果数组是一个值类型的数组(指数组中存的是值类型的元素),那么数组直接存值。如果是一个引用类的数组(指数组中存的是引用类型的元素)那么数组存的是引用(即内存地址)。

继承

C#中不支持多种继承

继承:父类中所有的数据成员和函数成员,都会继承到子类里面。父类里面公有的数据和函数成员才能在子类中访问。
官方文档:
继承(以及封装和多态性)是面向对象的编程的三个主要特征之一。 通过继承,可以创建新类,以便重用、扩展和修改在其他类中定义的行为。 其成员被继承的类称为“基类” ,继承这些成员的类称为“派生类” 。 派生类只能有一个直接基类。 但是,继承是可传递的。

实现继承
要声明派生自另外一个类,用下面语法:

class MyDerivedClass:MyBaseClass
{
   
	//MyDerivedClass是派生类,继承自基类MyBaseClass
}

MyDerivedClass是派生类,继承自基类MyBaseClass。
若类(或结构)也派生自接口,则用逗号分隔列表中得到基类和接口

public calss MyDerivedClass:MyBaseClass.IInterface1,IIterface2{
   }

父类声明的对象,可以用子类去构造,但是子类声明的对象不能用父类去构造,因为子类的方法,数据等要比父类更多,更强大。
父类A

 class A
    {
   
        public void F()
        {
   
            Console.WriteLine("这是父类的F方法");
        }
    }

子类B

  public void F()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值