VS2015中运行C#程序时: 编译时按ctrl+F5就不会闪退
语法:
数据类型[,…] 数组名称 = new 类型 [n,…];
int[] arrayHere= new int [6];
static void Main(string[]args)
{
intcount;
Console.WriteLine(“请输入准备登机的乘客人数");
count=int.Parse(Console.ReadLine());
//声明一个存放姓名的字符串数组,其长度等于乘客人数
string[]names = new string[count];
//用一个for 循环来接受姓名
for(inti=0;i
System.Object方法
名称 |
说明 |
Equals |
已重载。 确定两个Object实例是否相等。 |
Finalize |
允许Object在“垃圾回收”回收Object之前尝试释放资源并执行其他清理操作。 |
GetHashCode |
用作特定类型的哈希函数。 |
GetType |
获取当前实例的Type。 |
MemberwiseClone |
创建当前Object的浅表副本。 |
ReferenceEquals |
确定指定的Object实例是否是相同的实例。 |
ToString |
返回表示当前Object的String。 |
装箱和拆箱
int age = 17;
Object refAge= age;
int newAge= (int)refAge;
double newAge= (double)refAge;//错误,要具有相同类型
常用的还有as。用来将Object型还原成原本的引用或者值类型。
~ :将一个数按位取反,~操作符
switch...case
do while for循环等价于自动的循环if判断
语法:
foreach(数据类型元素(变量)in集合或者数组)
{
//语句
}
Foreach循环与for最大的差别就是不是单纯的if判断,而是节约效率的方式。因此推荐使用foreach。
Foreach不能对循环的对象进行修改
注意:Console.WriteLine("字母个数为:{ 0}",Letters);会出错。
{ 0}中不能有空格,应该为Console.WriteLine("字母个数为:{0}",Letters);
foreach(int i in array)
{
Console.WriteLine(t);//错误的写法Console.WriteLine(array[t]);
}
C#面向对象
结构程序设计的不足
1、数据与方法分离
2、代码不能重用
面向对象程序设计:封装、代码重用
1、抽象数据类型是仅由数据类型和可能在这个数据类型上进行的操作定义的。
2、使用者只能通过操作方法来访问其属性,不用知道这个数据类型内部各种操作是如何实现的。
student= new Student(); //如果缺少这一步编译器会报错
student.id= 200328013203194; //注意两个引用指向同一个对象和两个引用指向不同的引用的区别
虽然默认了,但是项目中一般不允许使用默认,必须写明。
classFurniture
{
const double salesTax = .065;
private double purchPrice;
private string vendor, inventoryID;
public Furniture(string vendor, stringinventID, double purchPrice)
{
this.vendor = vendor;
this.inventoryID = inventID;
this.purchPrice = purchPrice;
}
public string MyVendor
{ get { return vendor; } }
public double CalcSalesTax(doublesalePrice)
{ return salePrice * salesTax; }
}
class MyApp
{
static void Main()
{
Furniture f = new Furniture("aaa", "001", 1.2);
Console.WriteLine(f.salesTax);
Console.WriteLine(Furniture.salesTax);
f.purchPrice = 10;//错误的写法,访问类型,类外的对象不可以访问私有的。类的成员函数中可以访问同类型实例对象的私有成员变量
string str = f.MyVendor;
}
}
1、构造函数的特点:
–构造函数只能在对象创建时调用,即和new运算符一起被调用。
–构造函数和类具有相同的名字。
–构造函数可以有0个、1个或多个参数。
–构造函数没有返回值。
–每个类至少有一个构造函数,一个类可以有多个构造函数。
–如果没有为类定义构造函数,系统会自动为其定义一个缺省的构造函数。缺省构造函数不带参数,作用是将实例变量都清零。
–一旦为类定义了构造函数,则系统不会再为其定义缺省构造函数。
2、创建对象的格式:
类名 对象名=new 构造函数(参数类表);
public Student(string no, stringname,char sex,int age) :base(name,sex,age){ … }
public Point() : this(0,20){ … }
析构函数
在.net 编程环境中,系统的资源分为托管资源和非托管资源。
–托管资源:如简单的int,string,float,DateTime 等等,是不需要人工干预回收的。
–非托管资源:例如文件,窗口或网络连接,对于这类资源虽然垃圾回收器可以跟踪封装非托管资源的对象的生存期,但它不了解具体如何清理这些资源。在使用完之后,必须显式的释放他们,否则会占用系统的内存和资源,而且可能会出现意想不到的错误。
[访问修饰符] 返回类型 方法名称 ([参数列表])
{ 方法体;}
参数列表包括指参数个数、参数数据、返回值类型 C#不支持多重实现继承,允许类型派生于多个接口。
方法重载:同一个作用域,方法名相同,参数列表不同
调用时根据参数的不同进行区分调用那个方法
方法重写: 不同作用域,方法名相同, 参数列表相同------覆盖
访问父类、子类皆调用子类的重写方法
其实ref、out、看似好用,却会扩大变量的生命周期,使代码可读性下降。因此fxs的实际项目中会禁止使用
1).声明一个字段来存储属性值
2).编写一个属性声明,提供访问接口
2、属性的建立要使用属性声明,语法如下:
[访问修饰符]类型名 属性名
{ get
{ return 字段; }
set
{ 私有字段=value; }
}
3、属性说明:
Fxs的项目中一般会禁止使用封装、继承(本质是代码复用)和多态
封装把对象的所有组成部分组合在一起,三个作用
– 隐藏类的实现细节:使用方法将类的数据隐藏起来。
– 迫使用户去使用一个界面去访问数据:定义程序如何引用对 象的数据,控制用户对类的修改和访问数据的程度。
– 使代码更好维护:类的内部实现改变,对外接口可以不变
继承提供了创建新类的一种方法,继承对开发者来说就是代码共享。
– 通过继承创建的子类是作为另一个类的扩充或修正所定义的一个类。
– 子类从超类(父类)中继承所有方法和变量。
– 子类和超类之间是特化与范化的关系。
class 子类类名:父类类名{子类体}
(1)编译时的多态性:通过重载类实现的,系统在编译时,根据传递的参数个数、类型信息决定实现何种操作。
(2)运行时的多态性:指在运行时,根据实际情况决定实现何种操作。C#中运行时的多态性通过虚函成员实现。
动态绑定就是根据对象的类型决定调用哪个方法,而不是引用的类型。
(1).对于基类中要实现多态性的方法,用virtual关键字修饰。不允许再有static,abstract或override修饰符。
(2).对于派生类中的同名方法(覆盖)--相同的名称、返回类型和参数表,使用override关键字修饰。不能有new、static或virtual修饰符
实现多态性的核心和实质:
使用基类的引用指向派生类的对象,当程序运行时,编译器会自动确定基类对象的实际运行时类型,并根据实际类型调用正确的方法。
密封类:
密封类不允许派生子类。C#提供一种不能被继承的类,称为密封类。密封类的声明方法是在类名前加上sealed修饰符。修饰符abstract和sealed不能同时使用。
密封方法:还可以在重写基类中的虚方法或虚属性上使用sealed修饰符。这将使您能够允许类从您的类继承,并防止它们重写特定的虚方法或虚属性。在下面的示例中,C从B继承,但C无法重写在A中声明并在B中密封的虚函数F
class A
{
public virtual void F() { Console.WriteLine("A.F"); }
public virtual void F2() { Console.WriteLine("A.F2"); }
}
class B : A
{
public sealed override void F() { Console.WriteLine("B.F"); }
public override void F2() { Console.WriteLine("A.F3"); }
}
class C : B
{
// Attempting to override F causes compiler error CS0239.
// protected override void F() { Console.WriteLine("C.F"); }
// Overriding F2 is allowed.
public override void F2() { Console.WriteLine("C.F2"); }
}
类嵌套:
内层类被看成是外层类的一个成员。
内层类的方法可以访问外层类的私有成员。
类外当需要访问内层类,可以使用“.”符号。
内层类使用private关键字修饰,就相当于外层类的私有成员,不能在外层类之外被访问到
抽象类与接口:
抽象方法:类中的方法不提供具体实现,但该类的派生类必须实现这些方法,这些方法在C#中称为抽象方法。
抽象类:通过关键字abstract进行标记将类声明为抽象类;包含抽象方法的类称为抽象类。
当一个类从抽象类派生时,该派生类必须实际提供所有抽象成员的实现,否则,该派生类仍然是抽象类。如下面的示例所示:
abstract public Class A
{ public abstract void F(); //抽象方法}
abstractpublic Class B:A
{ public void G(){}; //附加方法}
public Class C:B
{ publicoverridevoid F(){……}} //抽象方法实现
接口:
语法结构:【访问修饰符】interface 接口标识符【:基接口列表】{ 接口体;}
接口成员访问权限为public,但不能加访问修饰符
接口成员不能有定义(即不出现 {})
接口的成员必须是方法,属性,事件或索引器,不能包含常数、字段、运算符、实例构造函数、析构函数或类型。
实现:类要继承某个接口用 ":",在类的定义中给出接口中所定义方法的实际实现,类中接口实现必须显示声明为public
publicinterface Interface1
{ voidfun1(inti);}//基成员
publicinterface Interface2
{ newvoid fun1(inti);//隐藏基成员
voidM1(inty);//添加新成员M1
}
publicclass cls1:Interface1
{public void fun1(inti){…..} }//实现接口方法
publicclass cls2:Interface2
{ public void fun1(inti){…..}
public void M1(inti){…….}
}
class Student : Comparable {...}
Comparable x = new Student();
3、接口可以作为参数和作为返回值使用
privateIHomeworkCollector CreateHomeworkCollector(stringtype){
switch (type)
{
case "student":
collector = new Student("Scofield",Genders.Male, 28, "越狱狱");
break;
......
} returncollector}
接口和抽象类的对比:
C#中的结构体struct
不支持继承(C++中可以),但可继承接口。它和类相似,可以包含构造函数,字段,属性,方法等,一般只是数据,有方法时用类
注意:
1. 结构不能包含显式的无参数构造函数。
2. 显式定义的构造函数必须带参数。
3. 对于结构中的实例字段成员,不能在声明时赋值初始化。
4. 在声明了结构类型后,可以使用new运算符创建结构对象。如果不使用new,那么在初始化所有字段前,字段保持未赋值状态且对象不可用。
5. 结构是值类型,类是引用型。
6. 结构不支持继承,但可继承接口。
以下任何一条,就应该使用类:
1.需要派生其他类型。
2.需要继承。
3.该类型作为方法参数传递。因为结构是值类 型,每次调用都要创建结构的副本。但结构放在数组中例外。
4. 该类型用作方法的返回类型。
错误类型:
1、语法错误:语法错误、缺少括号等;在编译时确定;易于确定
2、逻辑错误:错误的算法导致错误结果、公式错误等;在执行过程中确定;难以调试
3、运行时错误:内存泄漏、以零作除数、异常;在运行时确定;难以调试
Message获取描述当前异常的消息
Source获取或设置导致错误的应用程序或对象的名称(程序集的名称)
TargetSite获取引发当前异常的方法
StackTrace获取当前异常发生时调用堆栈上的帧的字符串表示形式
异常处理:
try...catch...finally
finally中无论有否异常该代码都会执行;catch处理异常代码try中的。try...catch可以嵌套使用。
定制处理未处理异常
Applicatioin.ThreadException += new ThreadExceptionEventHandler(method);
Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(method);
定制类中实现System.Object方法:ToString()函数(默认情况下,返回类名。应覆盖此方法),Equals()函数(Equals方法必须和GetHashCode方法成对出现)
序列化和反序列化:
序列化是将对象的状态存储到特定存储介质中的过程
反序列化则是从特定存储介质中的数据重新构建对象的过程
Array是抽象的基类,提供CreateInstance 方法来创建数组。
Array obj=Array.CreateInstance(typeof(string),10);
Array obj1=Array.CreateInstance(typeof(string),2,3,4);
SetValue()方法存储字符串;GetValue()方法检索数值组
int i = 100;
double d = 999.88d;
string s = "Hello World";
DateTime time = DateTime.Now;
ArrayList myList = new ArrayList();
myList.Add(i);
myList.Add(d);
myList.Add(s);
myList.Add(time);
myList.Insert(0, 200);
//myList.RemoveAt(0);
foreach (var p in myList)
{
Console.Write(p.ToString() + " ");
}
在C#控制台或应用程序中只能有一个Main()方法。