C#学习中基础知识笔记
一、使用变量、操作符和表达式
1.在c#中,multiplicative操作符(*,/和%)的优先级高于additive操作符(+和-)。
2.结合性:操作符*和/都具有左结合性。
3.赋值操作符是从右到左结合的。最右侧的赋值最先发生,被赋的值从右向左,在各个变量之间传递。
eg. myInt5 = myInt4 = myInt3 = myInt2 = myInt = 10;
4.递增(++)递减(–)操作符的前缀和后缀:
count++:先返回,再++; ++count:先++,再返回;
count - -:先返回,再 - -; - -count:先 - - ,再返回;
5.变量赋值时赋给一个变量的值必须具有和变量相同的类型。此外,声明隐式类型的局部变量是使用var关键字,var关键字指示编译器根据用于初始化变量的表达式来推断变量的类型,且使变量值类型规定下来。
eg:
var myVariable = 99;
var myOtherVariable = "Hello";
其中myVariable、myOtherVariable是隐式类型变量,分别为int和string类型。
注意:只有在提供一个表达式来初始化变量的时候才可以使用关键字var。
二、方法和作用域
1.C#声明方法
returnType methodName(psrameterList)
{
//主体语句
}
注:returnType(返回类型)是一个类型名,eg:int,string。。。
methodName(方法名)所要调用的方法名称;
psrameterList(参数列表)描述允许传给方法的数据类型和名称,可以多个,要用“,”隔开。
eg:
int addValues(int leftHandSize,int rightHandSize)
{
//...
//这里添加方法主体语句
//...
}
注:必须显式指定任何一个参数的类型和整个方法的返回类型,不能用var;
returnType(返回类型)换成void来指明方法不返回任何值。
若返回类型不是void,则主体内部要写关键字return,再加表达式,且表达式类型要和方法指定类型相同。且return语句写在最后,return后的语句不执行。
eg:
int addValues(int leftHandSize,int rightHandSize)
{
//...
return leftHandSize + rightHandSize
}
void时,可以省略return语句,或者直接写个“return;”
2.作用域:
(1)定义局部作用域:
在方法主体中定义一个作用域,主体内声明的任何变量都具有方法的作用域。方法结束则随着消失。只能有方法内部的代码访问,称这种变量为局部变量。且局部变量在不同方法中无法共享。
eg:
calss Example
{
void firstMethod()
{
int myVar;
...
}
void anothorMethod()
{
myVar = 42; //错误,变量越界(不在当前方法的作用域中)
...
}
}
(2)定义类的作用域:
在类主体中定义一个作用域,主体内声明的任何变量都具有方法的作用域。,C#中使用字段描述有一个类定义的变量可以实现字段在不同的方法之间共享信息。
calss Example
{
void firstMethod()
{
myField = 42; //ok
...
}
void anothorMethod()
{
myField = 42; //ok
...
}
int myField = 0;
}
变量myField在类内部定义且在firstMethod和anothorMethod方法的外部,故具有类的作用域。且要注意:字段可以再类的任何位置定义,与方法中的变量先声明再使用不同。
三.使用决策语句
1.使用switch语句需要注意的:
(1)switch只能用于基本数据类型,例如int或string;对于其他类型例如float和double只能用if;
(2)case标签必须是常量表达式,如果在运行时计算case标签的值,则必须使用if;
(3)casse标签具有唯一性,不允许两个case具有相同的值;
(4)例子:
switch (trumps)
{
case Hearts:
case Diamonds: //允许直通——case标签之间无额外代码
color = "Red"; //针对Hearts和Diamonds这两种情况都会执行的代码
break;
case Clubs:
color = "Black";
case = Spades: //出错—case之间有额外代码且没有使用break跳出
color = "Black";
break;
}
(5)break语句是用来阻止直通的最常见的方式,但也可用一个return或throw语句来替代他。
四,使用复合赋值和循环语句
1.复合赋值操作符,eg:+=、%=、/=、-=、*=。
其中操作符+=除了运用于数字,也可用在字符串,eg:
string name = “STeve”;
string greeting = “Helllo”;
greeting += name;
Console.WriteLine(greeting); //输出的为“Hello STeve”
但只可+=可用在字符串上,其他操作符不行。
2.for语句中在“初始化”部分声明的新变量,其作用域值限制在for语句的主体中。一旦for语句结束,变量就会消失。
其次,由于每个变量只在各自的作用域内有效,所以多个for语句中可以使用相同的变量名。
五,管理错误和异常
1.假设:一个异常与try快末尾的多个catch处理程序匹配,会如何处理?
答:一个异常发生之后,将运行由“运行时”发现的第一个匹配的异常处理程序,其他处理程序会被忽略。eg,假设让一个处理程序捕捉Exception,后面又让一个处理程序捕捉FormatException,后者永不执行。因此,在一个try块之后,应该将较具体的catch处理程序放在较常规的catch处理程序之前。如果没有一个较具体的catch处理程序能够与异常匹配,就执行较常规的catch处理程序。
2.无论编译一个怎样的应用程序,都可以使用checked和unchecked关键字选择性打开和关闭程序的一个特定部分的整数溢出检查。
checked语句中的任何整数运算溢出都会抛出一个OverflowException异常:
int number=int.MaxValue;
checked
{
int willThrow=number++;
Console.WriteLine("永远都执行不到这里");
}
or:
int willThrow=checked(int.MaxValue+1);
unchecked则对于块中的整数运算都不会检查,就也不会抛出OverflowException异常:
int number=int.MaxValue;
unchecked
{
int wontThrow=number++;
Console.WriteLine("会执行不到这里");
}
or:
int wontThrow=unchecked(int.MaxValue+1);
但checked和unchecked关键字只能适用于int和long等整型执行的运算,不能来控制浮点运算。浮点运算永远不会抛出一OverflowException异常。
3.一个异常抛出后,它会改变程序的执行流程。这就意味着不能保证当一个语句结束之后,后面的语句肯定会运行。要注意,例如当一个语句的作用是释放它之前的一个语句获取的资源,那么就必须确保语句的执行。
4.可以使用finally块来保证某些语句的执行。Finally块要么紧接在try块之后,要么紧接在try块之后的的最后一个catch处理程序之后。只要程序进入与一个finally块相关联的try块,则finally块始终都会运行。
第二部分
创建并管理类和对象
1.一个类容纳的信息存储在字段中,类要提供的功能用方法来实现。
2.定义一个类时,程序只需要创建类的一个实例,然后调用类的方法。而使用一个类的程序不应该关心累的内部实际如何工作,这就是封装的中心思想。
封装的目的:(1)将方法和数据合并到一个类中,换言之,为了支持分类;
(2)控制对方法和数据的访问,换言之,为了控制类的使用。
3.类的主体中包含普通的方法和字段(也即变量)
4.关于方法和字段的命名:
public的标识符应该以大写字母开头,eg:public Area中的方法Area要以”A”开头;
非public的标识符(其中包括局部变量)应该以小写字母开头。
一个例外!:类名应该以大写字母开头,而构造器必须完全与类同名。所以一个private构造器也应该以大写字母开头。
5.构造器必须完全与类同名,但它没有返回类型(就连void都不能写)。构造器写法:与类同名的public/private方法(默认构造器的话不返回任何值)。
构造器的本质就是方法。
重载构造器后,生成应用程序时,编译器会根据为new操作符指定的参数来判断应该使用哪个构造器。 要注意的是:一旦为一个类写了任何构造器,编译器就不再自动生成默认构造器,如需用到,就必须手动写默认构造器。
1.理解null和可空类型:
null值常用于初始化引用类型,其本身就是一个引用。但不能把它复制给一个值类型,{eg: int i = null;// **非法!**
}
但是利用修饰符“?”,可以讲一个变量声明为一个可空值类型,可空值类型在行为上和普通值类型相似,但可以将一个null值赋给它。
{eg: int? i = null; // 合法
} 可以将值类型的常量赋给一个可空类型,但反之不行!
可空类型包含两个属性&#