跬步之积–一些磨人的小知识点
前言:
自己在看C#视频的时候,有些知识点虽小,但是总觉得自己不是很清楚,所以趁着这个总结的时机,来整理整理吧。
一. try-catch语句
捕获输入后的异常,在main函数中添加代码如下:
int number = 0;
while (true)
{
try
{
Console.WriteLine("请输入一个整数:");
number = int.Parse(Console.ReadLine()); //当输入的不是整数时抛出异常
if (number <0 || number > 100) //当数值不在0到100之间时抛出异常
throw new ArgumentOutOfRangeException("number", "数值应该在100以内");
}
catch (ArgumentOutOfRangeException e) //捕获“数据不在指定范围”异常
{
Console.WriteLine(e.Message); //输出异常消息的内容
continue; //重新输入整数
}
catch (FormatException e) //捕获“字符串格式不正确”异常
{
Console.WriteLine(e.Message); //输出异常消息的内容
number = 100; //数值取最大值
continue; //重新输入整数
}
finally
{
Console.WriteLine("输入整数为{0}", number); //输出数值
}
break;
}
小编的理解:
模板:
try
{ //这里是TRY开始,程序开始捕获异常
//如果有异常 进入 catch {} 然后再进入 finally{}
//如果没异常 直接进入 finally{}
conn.Open();
return (conn.State == ConnectionState.Open);
//Try结束
}
catch (SqlException ex)
{
//catch 有异常才会进入我这里
return false;
}
finally
{
//无论如何都会进入我这里,这里适合做一些释放资源的事情
//这里可以舍去不用
conn.Close();
}
二. switch 语句
Switch 语句中多个case值,执行同一个语句块。
Switch(prime)
{
Case 1:
Case 2:
Case 3:
Case 5:
Case 7:
Console.writeLIne(“{0}为素数”,prime);
break;
Case 4:
Case 6:
Case 8:
Case 9:
Case 10:
Console.WriteLine(“{0}为合数”,primt);
break;
default:
break;
}
三. 函数的递归调用和值传递
从控制台输入一个正整数,然后通过计算阶乘的函数来计算该正整数的阶乘,最后从控制台输出结果
代码如下:
/// 计算n的阶乘
static decimal Factorial (decimal n)
{
if (n==1) return 1;
// 将1作为函数返回值
else return n*Factorial(n-1);
//计算n乘以(n-1)的阶乘,并作为参数返回值
}
Console.WriteLine(“请输入一个整数:”);
decimal number=decimal.Parse(Console.ReadLine());
Console.WriteLine(“{0}的阶乘为{1}”,number,Factorial(number));
四.值传递和引用传递(老生常谈,但还是要弹一弹)
引用类型
Static void Exchange(ref int number1, ref int number2)
{
Int temp =number2;
//将第二个数存放到临时变量中
Number2=number1;
//将第一个数的值付给第二个数
Number2=temp
// 将临时变量赋值给第一个数
}
上例中的number1和number2 为函数的两个整数参数,参数前面的ref关键词表示该参数的值类型为引用传递。
引用传递,即将数值本身传递到函数体内,在函数中对该参数的修改会造成对数值本身的修改。而例3中的参数为值传递,在函数中对该参数的修改不会造成对数值本身的修改。
咱们聊聊引用类型和值类型:
1) 值类型的变量本身包含他们的数据,而引用类型的变量包含的是指向包含数据的内存块的引用或叫句柄。(值类型,找个人,本尊在此;引用类型,找个人,只是给你方向,自己找去吧)。
2)值类型变量存储在堆栈。每个程序在执行时都有自己的堆栈,其他程序不能访问。
3) 引用类型存储在堆。引用类型存贮实际数据的引用值的地址。
推销一把,小编写了一篇 【C#】堆 栈 之辨,欢迎来阅~
4) C#中的引用类型有4种:(类、代表、数组、接口)
五. 装箱和拆箱
作用: 数据类型的转换
装箱:
将一个值类型隐式转换成一个object类型,或吧这个值类型转换成一个把该值类型应用的接口类型。
拆箱:
对象类型显式地转换成一个值类型,或将一个接口类型显式地转换成一个执行该接口的值类型。
六. 重载和override
重载
Class Cat
{
Private string name= “”;
//
Public Cat (string name)
{
This.name =name;
}
//
Public Cat()
{
This.name =”无名”;
}
//
Public String Shout()
{
Return “我的名字叫” + name + “ 喵”;
}
}
重载 是指方法名称相同, 只是参数个数或类型不同. 方法功能是相同的
例如这里的Cat()和 Cat(string name)
重写
override重写,是在子类中重写父类中的方法,两个函数的函数特征(函数名、参数类型与个数)相同。
注意事项:
1.重写基方法必须具有与override方法相同的签名。
2.override声明不能更改virtual方法的可访问性,且override方法与virtual方法必须具有相同级别访问修饰符。
3.不能用new、static、virtual修饰符修改override方法。
4.重写属性声明必须指定与继承的属性完全相同的访问修饰符、类型和名称。
5.重写的属性必须是virtual、abstract或override。
6.不能重写非虚方法或静态方法。
7.父类中有abstract,那么子类同名方法必定有override,若父类中有 virtual方法,子类同名方法不一定是override,可能是overload。
8.override必定有父子类关系。
举个栗子
using System;
class TestOverride
{
public class Employee
{
public string name;
//Basepay 被定义为保护型, 只能被自己的类和继承子类调用
protected decimal basepay;
// 为name和basepay 赋值
public Employee(string name, decimal basepay)
{
this.name = name;
this.basepay = basepay;
}
// 为能被重写,声明为 virtual型
public virtual decimal CalculatePay()
{
return basepay;
}
}
// 从Employee中产生一个继承子类
public class SalesEmployee : Employee
{
// 新的字段将会影响Basepay
private decimal salesbonus;
// 构造器调用被扩展继承的类,给salesbonus变量赋初值
public SalesEmployee(string name, decimal basepay,
decimal salesbonus) : base(name, basepay)
{
this.salesbonus = salesbonus;
}
// 重现 CalculatePay 方法,将重现 bonus
public override decimal CalculatePay()
{
return basepay + salesbonus;
}
}
static void Main()
{
// 新建一些employee
SalesEmployee employee1 = new SalesEmployee("Alice",
1000, 500);
Employee employee2 = new Employee("Bob", 1200);
Console.WriteLine("Employee " + employee1.name +
" earned: " + employee1.CalculatePay());
Console.WriteLine("Employee " + employee2.name +
" earned: " + employee2.CalculatePay());
}
}
C# 允许派生类包含与基类方法名称相同的方法。
基类方法必须定义为 virtual。如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警告,该方法将有如存在 new 关键字一样执行操作。
如果派生类中的方法前面带有 new 关键字,则该方法被定义为独立于基类中的方法。
如果派生类中的方法前面带有 override 关键字,则派生类的对象将调用该方法,而不调用基类方法。可以从派生类中使用 base 关键字调用基类方法。
override、virtual 和 new 关键字还可以用于属性、索引器和事件中。