学习C#.net已有一段时间了,学的快忘的也快,在博客园开博也是很久很久了,是时候留下点东西了,从这篇笔记开始,将对前面所学编程知识进行复习。要知道,想让我坚持一件事情是很不容易的,我不知道这次能走多远--第1天就这样兢兢战战滴来了!
类是C#中的一种特殊又复杂的数据类型,但是不要怕,没那么简单,也没那么难!
C#中如何定义类
class Person
{
}
默认情况下,class关键字前没有写访问修饰符,那类的访问修饰符就是internal,当然也可以写上,但这又是没有必要的,默认就是internal嘛。
当然类还可以指定其他访问修饰符:public、private、protected、abstract、sealed等,还可以组合使用。
1、C#类的成员
类的成员包括字段、属性、方法、构造函数等。
这些成员也可设置访问权限,和类一样。
还可以使用static关键字将其声明为静态成员。静态成员属类级别概念,它不属于类的实例(对象)。
2.1、 字段
字段由三部分组成:访问修饰符、字段类型、字段名称。
字段一般声明为private
1 public class Person 2 { 3 private string name; 4 public int age; 5 protected bool sex; 6 }
用关键字readonly或const定义字段
1 public class Person 2 { 3 private readonly string name;//只读字段,不需要在定义时初始化,可在构造函数中完成初始化
4 public const int age=18;//加了const就要给定初始化值
5 protected bool sex; 6 }
使用关键字static来声明静态字段。
静态字段和实例字段的区别是:静态字段必须通过类.字段名访问,实例名则通过类的对象.字段名
1 public class Person 2 { 3 public static string name;//静态成员字段
4 public const int age=18;//实例成员字段
5 }
2.2 属性
属性是字段的扩展。
为了不让外界随意修改成员的值,最好将字段设置为private。
C#中提供了一种属性机制,可以灵活的控制外界对字段的读写。
1 public class Person 2 { 3 private string name; 4 //方法是类的“行为”,接受外界设定的“名字”值
5 public void SetName(string value) 6 { 7 this.name = value; 8 } 9 //返回字段name的值
10 public string GetName() 11 { 12 return this.name; 13 } 14 private int age; 15 //方法是类的“行为”,接受外界设定的“年龄”等值
16 public void SetAge(int value) 17 { 18 this.age = value; 19 } 20 //返回字段age的值
21 public int GetAge() 22 { 23 return this.age; 24 } 25 //执行问好的动作
26 public void SayHello() 27 { 28 Console.WriteLine("大家好,我是" + this.name + ",我今年" + this.age + "岁了"); 29 } 30 //上面对字段的读取和写入是用方法实现. 31 //而C#提供的属性机制更方便,使我们不用再麻烦的调用方法就可以对字段进行读写。
32 public string Name 33 { 34 get { return name; } 35 set { name = value; } 36 } 37 //简写
38 public string Name { get; set; } 39 }
可以使用只写get或给set设置private来定义只读属性,只写属性也一样。但只是不能被外界读取(比如Main方法不能读取它)
还可以给属性加入逻辑控制代码,比如人的年龄一般在0-120之间,为了避免用户输入这个范围之外的数值,可在属性中添加限制代码或抛出异常代码。
1 private int age; 2 public int Age 3 { 4 get
5 { 6 return age; 7 } 8 set
9 { 10 if (age <= 0 || age > 120) 11 { 12 throw (new ArgumentOutOfRangeException("AgeIntPropery", value, "年龄必须在0-120之间")); 13 } 14 age = value; 15 } 16 }
2.3 方法
Main方法是每个C#应用程序的入口,程序启动时,Main由公共语言运行时(CLR)负责调用。
方法由方法签名和一系列语句的代码块组成。
方法就是一堆可以重复使用(复用)的代码段,执行过程中无法确定的数据以参数形式传递;方法执行的执行结果以返回值进行返回。
方法签名包括方法的访问级别(如public、private)、可修饰符(如abstract、static等)、方法名和参数来。
方法可以没有参数,可以没有返回值(void).return返回处理结果,执行return之后方法内部的代码就执行结束了。
1 public class Person 2 { 3 //这是一个有参数无返回值的方法
4 public static void SayHello() 5 { 6 Console.WriteLine("大家好!"); 7 } 8 //这是一个由参数有返回值的方法
9 public int Print(int age) 10 { 11 Console.WriteLine("我的年龄是" + age); 12 return age; 13 } 14 }
因为定义的是实例方法,要调用实例方法必须实例化一个对象。
带有static关键字的方法叫做静态方法,静态方法属于类级别,不能通过实例进行访问,必须通过Person.SayHello()方式调用。
class Program { static void Main(string[] args) { Person p=new Person(); p.Print(18); Person.SayHello(); } }
方法的重载
同一个类中,允许存在一个以上的同名方法,只要其参数个数、参数类型或参数顺序不同即可。与返回值无关。
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Person p = new Person(); 6 //参数个数、类型、顺序不同区分调用哪一个方法重载
7 p.Print("Lucy") 8 p.Print(1, "Sean"); 9 p.Print("Jack", 2); 10 Console.ReadKey(); 11 } 12 } 13 public class Person 14 { 15 public int Print(int age) 16 { 17 Console.WriteLine("年龄:" + age); 18 return 100; 19 } 20 public void Print(string name) 21 { 22 Console.WriteLine("我的名字叫:" + name); 23 } 24 public void Print(int age, string name) 25 { 26 Console.WriteLine("我的名字叫:" + name + "年龄是:" + age); 27 } 28 public void Print(string name, int age) 29 { 30 Console.WriteLine("我的名字是:" + name + "今年" + age); 31 } 32 }
构造函数
构造函数是创建对象,并且在创建完成前对类进行初始化的特殊函数。
有实例构造函数和静态构造函数两种。
特征:
也可以这么理解:
当你在主方法中new一个对象时,Person p=new Person();这个Person()是不是很像在调用一个方法(函数),这个方法(函数)其实就是构造方法,不写的话默认会给出一个无参构造方法;
那么构造方法怎么写:
因为在主方法中调用时是Person p=new Person(),显然要先读取Person这个类,那么构造函数也要和这个类名一致。
private和protected修饰的是私有构造函数
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 /*
6 Person p = new Person(); 7 //参数顺序和参数类型,参数个数不同都构成重载。 8 p.Print("Sean", 1); 9 p.Print(2, "Shawn");*/
10 //一般写了有参构造函数默认无参就没了,如果要用需要自己写出来
11 Person p1 = new Person(); 12 Person p2 = new Person("Sean"); 13 Person p3 = new Person() { Name = "Jack", Age = 18 };//简写的,属性赋值
14 Console.ReadKey(); 15 } 16 } 17 public class Person 18 { 19 private string name; 20 public string Name { get; set; } 21 private int age; 22 public int Age { get; set; } 23 public Person() 24 { 25 name = "Tom"; 26 } 27 public Person(string name)//这是公共构造函数
28 { 29 //使用this关键字来引用字段name,与参数name(局部变量)区别开来。
30 this.name = name;//this代表当前类的实例对象。
31 } 32 }
私有构造函数典型应用是设计模式中单例模式的实现:
1 class Person 2 { 3 private string name; 4 public static Person person; 5 public string Name; 6 { 7 get{ return this.name;} 8 } 9
10 //私有构造函数,只能在类内部调用 11 //也就是说类的实例化只能在类定义时被实例化
12 private Person() 13 { 14 this.name="sean"; 15 } 16 //静态方法,用于返回类的实例
17 public static Person GetInstance() 18 { 19 person = new Person(); 20 return person; 21 } 22 } 23
24 class Program 25 { 26 static void Main(string[] args) 27 { 28 //通过调用GetInstance()静态方法返回一个Person的实例 29 //不能使用new Person()创建实例
30 Person person=Person.GetInstance(); 31 Console.WriteLine("类实例的属性为:"+person.Name); 32 Console.Read(); 33 } 34 }
静态构造函数
结合下面代码,在Main方法中,创建两个Person对象,启动程序会发现,首先打印的是“静态构造函数被调用了”,随后才是两个“实例构造函数被调用了”。
1 private static string name; 2 //静态构造函数,仅执行一次
3 public Person() 4 { 5 Console.WriteLine("实例构造函数被调用了"); 6 }
7 static Person() 8 { 9 Console.WriteLine("静态构造函数被调用了"); 10 name="sean"; 11 } 12 public static string name 13 { 14 get{return name;} 15 }
析构函数
用于在类销毁之前释放实例所使用的托管和非托管资源。
定义析构函数,需要注意:
1 class Person 2 { 3 ~Person() 4 { 5 Console.WriteLine("析构函数被调用了"); 6 } 7 }
该析构函数隐式的调用了基类Object的Finalize方法,上面代码中的析构函数将隐式的转换为如下代码:
protected override void Finalize() { try { Console.WriteLine("析构函数被调用了"); } finally { //调用FinalLize方法
base.Finalize(); } }
索引器 当一个类包含数组成员时,索引器的使用将大大简化对类中数组成员的访问。索引器的定义类似于属性,也具有get访问器和set访问器,代码示例:
[修饰符] 数据类型 this[索引类型 index]
{
get{//返回类中数组某个元素}
set{//对类中数组元素赋值}
}
数据类型对应intarray字段的数据类型,索引类型表示该索引器使用哪一个类型的索引来存取数组元素,可以是整型,也可以是字符串;this表示所操作的是类对象的数组成员,可以简单理解为索引器的名字(注意,索引器不能自定义名称)
1 class Person 2 { 3 //可容纳10个整数的数组
4 private int[] intarray = new int[10]; 5 //索引器的定义
6 public int this[int index] 7 { 8 get
9 { 10 return intarray[index];//返回类中数组某个元素
11 } 12 set
13 { 14 intarray[index] = value;//对类中数组元素赋值
15 } 16 } 17 }
如何使用索引器
Main方法中:
1 Person person = new Person(); 2 Person p3 = new Person(); 3 p3[0] = 15; 4 p3[1] = 32; 5 p3[2] = 20; 6 p3[3] = 19; 7 Console.WriteLine(p3[2]);
索引器和属性的区别:索引器也是一种对私有字段的一种访问,不同的是索引器是对数组类型的私有字段进行访问,而属性是对简单数据类型的一种访问。
3. 类和结构体的区别
1 struct Point 2 { 3 private int x; 4 private int y; 5 public Point(int i1, int i2) 6 { 7 this.x = i1; 8 this.y = i2; 9 } 10 }
4.匿名类
C#中的匿名类: var p = new { Id=5,Name="rupeng",Age=8} 通过反编译看到其实还是生成一个类。
第一步:定义一个类,类有三个属性Id,Name,Age其类型根据=右边的值来推断。
第二步:创建这个类的对象,用这个变量p1指向它。