变量声明
int a=1;double a=1.0;char a='a';string a="abc";字符串可相加。bool a=true;
数组:
int[] a={1,2,3};int[] a=new int[3];括号中不用写数字。int[] a; a=new int[10];不赋值都就赋0。a=new int[]{1,2,3}括号中可以不写数字。a[0]=2修改数组中的值。不能直接a={1,2,3}。构造数组应使用new int[]{1,2,3}(类似于把这个叫做数组常量而不是c中的那样)。
a.Length返回数组长度。
foreach
foreach(int i in a){
}取数组中的每一个值
字符串
str.Length返回长度。str[3]索引其中一个字符。
str.ToLower(),str.ToUpper(),str.Trim()去除空格,str.TrimStart(),str.TrimEnd()
str.Split(",")分割,返回字符串数组。"ab,cd,ef"分割为长度为3的数组。
判断字符串相等可直接用等号。
强制类型转换
int a=97; char b;
b=(char)a;
数字字符串转换为数值Convert.ToInt32(),以及其他Convert下方法。
数值转换为字符串,Convert.ToString()或a+"";
转义字符
"\\a\\b"输出为\a\b
@"\\a\\b"转义字符不生效,输出\\a\\b,但如果要输出引号(")就要用两个引号("")
输入输出
Console.ReadLine();返回值为字符串,string str=Console.ReadLine();
要得到数值的话:int a=Convert.ToInt32(str);或者int a=Convert.ToInt32(Console.ReadLine());输入的值不是数字的话会报错
Console.WriteLine();
字符串格式化输出
console.writeline("{0}+{1}={2}",a,b,c);0、1、2表示后面参数的位置,可以多次用或不用。console.writeline("{0}+{0}={2}",a,b,c);
关系、逻辑运算符
跟c一样&& || !
条件
if(){
}else if(){
}else{
}
switch语句
switch(){
case ...:
...
break;
case ...:
...
default:
...
}
while
while(){
}
do{
}while();
for循环
for(int a=0;a<10;a++){
}
作用域
for(int a=0; ; ){}a是局部变量。与c不同,子作用域不能取声明与父作用域相同名字的变量。
int a;if(){int a;}报错。
函数
static void f(int a,string b,int[] c){
}
static void f(params int[] a){},传递任意个参数,参数自动转化为数组a。f(1,2,3);即可以在f中使用数组a,a为{1,2,3}。与上面的传递数组参数不同。必须放在参数列表的最后。
函数的重载
定义多个函数,函数名相同,参数不同。static int f(int a){}和static int f(double a){},返回类型不所谓。根据传入的参数类型选择不同的函数。
const常量
const int a=1;a就不能更改。再给a赋其他值会报错。
enum枚举
定义在main之外。enum A{a,b,c}。创建变量,A a=A.a,创建枚举类型A的变量a,并给a赋值A.a
其中的值本质为整数,默认从0递增,可用(int)强制类型转换,int a=(int)A.a。
结构体
定义在main外。定义struct A{public int a;public double b;} 创建变量A a;a.a=1;a.b=1.0;
结构体数组,A[] a=new A[3];作为参数,static void f(A a){}
结构体内的函数,struct A{public void f(){...}}。调用,A a;a.f();
也可以有构造函数,就可以用new A();来构造。
委托
定义delegate int A(int a ,double b);声明变量A a;如果有返回类型和参数类型相同的一个函数,那么a就能赋值为那个函数。假设有static int f(int a,double b){},a=f;a();就相当于f();如有其他同返回类型和参数类型也可赋值为其他的函数。
用法之一可作为参数,static void f(A a){a();},假设有一符合的函数F(),传入f(F);相当于把一个函数作为另一个 函数的参数。如果不想传入参数,可以传入null即f(null)。可在f()中判断a是否为空,即加入if(a!=null){}。
异常处理
try{...}catch(异常类型){该异常类型时运行的代码}finally{是否异常都会运行的代码},try中的一行出错,后面的就不会执行,直接进入到catch。例:检测用户非法输入,非法要重新输入,但重新输入后还要检测是否合法,所以用循环while(true){try{...break;}catch(){...}},其中try最后一行加break;因为如果输入合法就会执行break跳出循环,否则不会执行而会直接执行catch。
类
class A{public int a;public void f(){}}与结构体类似。实例化与结构体不同。A a=new A();a.a=1;a.f();
public和private,private属性不能在外部访问。给class前面加public能在其他项目中访问。
构造函数
无返回类型,函数名与类名相同class A{public A(){}},示例化时就会调用构造函数,可以通过构造函数为实例对象属性赋初值,如果不写构造函数,系统会自动加一个空的,示例对象的属性默认赋值为0或null。
class A{public int a;public A(int b){a=b}},A a=new A(1);a.a的值就为1。
可以写多个构造函数,相当于函数的重载,实例化时会自动调用符合参数列表的构造函数。如果只写了一个有参数的构造函数,那么实例化时必须要按照这个构造函数传入参数,不能像之前一样new A();不写参数。
函数的形参与类的属性重名的话,那么要加this.表示类的属性而不是形参。例:class A{public int a;public A(int a){this.a=a}}。
属性
class A{private int ab;public int Ab{get{return ab;}set{ab=value;}}}现在称Ab为属性(属性名为数据成员名的首字母大写),ab为数据成员,使用Ab时自动调用get内的代码,给Ab赋值时自动调用set内的代码,传入参数和返回值类型都为前面定义的int,形参名为value,可以看成简化的set方法和get方法来对私有数据成员赋值或取值。get和set前面也可加private,这样就不能在外部调用。也可以只写set或只写get,这样可以控制只读或只写。例:A a=new A();a.Ab=1;则a.ab的值被赋为1,console.writeline(a.Ab)则输出a.ab。
也可以简写为public int Ab{get;set;}不写get和set的函数体。类中也可以只有属性Ab没有数据成员ab,即class A{public int Ab{get;set;}}。
匿名类型
var a=1;var b=“abc”;使用var不指定变量的类型,变量的类型由赋值的时候确定。第一次赋值的时候就确定类型了,之后再赋值就不能赋其他类型了。
引用类型
有两个引用类型a,b。变量a,b实际存储的是地址,令b=a;那么b和a指向同一个地址,用b修改值,a中的值也会改变。字符串、数组、类为引用类型。结构为值类型。
继承
class A{} class B:A{}。private数据子类能继承但是也不能访问,可使用protected。
前面加this.访问当前对象的数据,base.访问父类数据。
可以用父类声明变量但用子类构造。A a;a=new B();a实际上是B类,但却不能调用B中特有的方法和数据。不能声明子类但用父类构造。
调用子类的构造函数时,必定先调用父类中的构造函数,默认调用父类中的无参的构造函数。若要调用父类中有参的构造函数,假设A为有参的构造函数,class B:A{public B(int a,int b,int c):A(b,c){}},参数b,c就会传入A的构造函数。
方法重写
一 父类加virtual,子类加override。class A{public virtual void f(){}},class B:A{public override void f(){}}。这样用父类声明子类构造时,调用的方法是子类中重写的方法。(多态)
二 父类中不变,子类中加new。class B:A{public new void f(){}}。这样用父类声明子类构造时,调用的方法是父类中的方法,而不是重写后的方法。
抽象类
abstract class A{public abstract void f();}抽象方法定义在抽象类中,抽象方法没有函数体,不能调用。抽象类不能实例化,要通过子类继承重写抽象方法后才能实例化并调用该方法。可以用抽象类声明用子类构造对象,这样调用方法是子类重写后的。class B:A{public override void f(){}}。抽象类中也可以有普通正常的数据和方法。
密封类、密封方法
在类前加sealed,这个类就不能被继承。在一个重写方法前加sealed,这个方法就不能再被重写。
readonly声明只读字段,初始化后就不能改了
static
静态数据。静态方法,只能使用静态数据。静态类,只能有静态成员,不能实例化。只能通过类名调用。
接口
interface IA{public void f();},一般在名字前加I,只有方法名,没有方法体,跟抽象类类似。实现接口,class A:IA{public void f(){}}实现具体方法内容。可以实现多个接口。可以用接口声明对象用类构造,跟父类声明子类构造类似。
接口也可以继承另一个接口。interface Ia{public void f1();},interface Ib:Ia{public void f2();},实现接口Ib时,就要同时实现接口Ia中的方法。
索引器
在类中定义public int this[int index]{get{}set{}},可以改返回类型和索引下标的类型。创建该类对象,可以用下标进行索引,假设A a=new A();用a[index]索引,索引的效果是在set和get中自己定义的。
运算符重载
以==为例。class A{public int a;public static bool operator==(A a1,A a2){}},两个A类对象使用==时就会调用重载里面的代码。描述符static,operator。
列表
List<int> a=new List<int>(){1,2,3};“<>”中为数据类型。还要使用它的命名空间才能用。相当于动态数组。a.add();a.count();a[0];a.capacity;a.insert(位置,数据);a.remove();a.indexof();list.sort();。new List<int>(int)括号中参数可以指定初始列表的默认大小。
泛型
泛型类,class A<T>{public T a;public A(T a){}},T为数据类型。使用时,A a=new A()<T>;T换成想要使用的类型。
泛型方法,public T f<T>(T a){}。泛型就是指调用的时候再确定参数或数据的类型。
tostring
每个类中都有一个隐藏的ToString()方法(继承自父类),假设把类对象打印输出就是默认调用了该方法,把类对象转换为字符串输出。可以重写该方法,public override string ToString(){}
equals方法
调用equals方法判断变量是否相等。int a=1;int b=1; a.equals(b)返回true。类对象也可以用,但类对象是引用类型,两个值相同的类对象还是返回false,可以在类中重写equals方法来自定义判断的逻辑。public override bool equals(object a){}