首页 > 代码库 > 飘过来学C#系列(1)之------对象和类型
飘过来学C#系列(1)之------对象和类型
1.1 类和结构
类是存储在堆上的引用类型,而结构是存储在栈上的值类型.
类使用的关键词是class,而结构使用的是struct生声明.
1.2 数据成员
数据成员是包含类的数据-----字段,常量和事件的成员.数据成员可以是静态数据.类成员总是实例成员,除非用static进行显式声明.
常量与类的关联方式同变量与类的关联方式.使用const关键字来声明常量.
如果声明为public就可以在类的外部访问它
事件是类的成员,在发生某些行为(如改变类的字段或属性,或者进行了某种形式的用户交互操作)时,
它可以让对象通知调用方.客户可以包含所谓"事件处理程序"的代码来响应该时间.
1.3 函数成员
函数成员提供操作类中数据的某些功能,包括方法,属性,构造函数和终结器,运算符以及索引器.
1.4 方法
(1)声明方法
方法定义包括任意方法修饰符,返回值的类型,然后依次是方法名和输入参数的列表和方法体.
public string GetUserName([parameters])
{
return ;
}
如果没有返回值指定void
(2)方法的调用
string name=GetUserName([parameters]);
(3)方法传递参数
class Program{ static void SomeFunction(int[] ints, ref int i) { ints[0] = 100; i = 100; } public static int Main() { int i = 0; int[] ints = { 0, 1, 2, 4, 8 }; Console.WriteLine("i=" + i); Console.WriteLine("ints[0]=" + ints[0]); Console.WriteLine("Calling SomeFunction."); SomeFunction(ints,ref i); Console.WriteLine("i=" + i); Console.WriteLine("ints[0]=" + ints[0]); Console.ReadKey(); return 0; }}
结果为
i =0
ints[0]=0
Calling SomeFunction
i = 100
ints[0]=100
ref关键字,如果把一个参数传递给方法,且这个方法的输入参数前带有ref关键字,则该方法对变量所做的任何改变都会影响原始对象的值.
(4)out参数
在方法的输入参数前面加上out前缀时,传递给该方法的变量可以不初始化.该变量通过引用传递,所以在从被调用的方法中返回时
对应方法对该变量进行的任何改变都会保留下来,在调用该方法时,还需要使用out关键字,在与定义该方法时一样.
(5) 方法的重载
声明同名但参数个数或类型不同的方法即可.
class MyClass{ int DoSomething(int x) { DoSomething(x,10); } int DoSomething(int x,int y) { //方法实现 }}
1.5 属性
属性其实就是一个方法或一对方法,在客户端代码看来就是一个字段.例如Windows窗体的Height属性.
public string Name{ get { return _name; } set { _name = value; }}
1.6 构造函数
一般情况下如果没有提供任何构造函数,编译器会在后台创建一个默认的构造函数.如果提供了带参数的构造函数
编译器就不会自动提供.
public class MyNumber{ private int number; private MyNumber(int number) { this.number = number; }}
(1)静态构造函数
为何使用静态构造函数:当我们第一次使用类之前,从外部源中初始化这些静态字段和属性的时候.
public class UserPreferences{ public static readonly Color BackColor; static UserPreferences() { DateTime now = DateTime.Now; if(now.DayOfWeek == DayOfWeek.Saturday||now.DayOfWeek == DayOfWeek.Sunday) BackColor= Color.Green; else BackColor = Color.Red; } private UserPreferences() { }}
编译UserPreferences.BackColor.ToString();
得到的结果 Red如果在周末执行Green
(2)构造函数相互调用
class Car { private string description; private uint nWheels; public Car(string description,uint nWheels) { this.description = description; this.nWheels = nWheels; } public Car(string description) { this.description = description; this.nWheels = 4; } }
这两个构造函数初始化了相同的字段,显然最好把所有的代码放在同一个地方,利用构造函数初始化器可以实现.
class Car { private string description; private uint nWheels; public Car(string description,uint nWheels) { this.description = description; this.nWheels = nWheels; } public Car(string description):this(description,4) { } }
只读字段
只读字段即不可修改.readonly关键字比const灵活得多,允许把一个字段设置为常量,但还需要执行一些计算,以确定它的初始值.
其规则是可以再构造函数中给只读字段赋值,但不能再其他地方赋值.只读字段还可以是一个实例字段,而不是静态字段.
class Car
{ public static readonly uint MaxDocuments; static Car() { MaxDocuments = DoSomethingToFindOutMaxNumber(); }}
在本例中,字段是静态的,每次运行程序的实例,只需存储MaxDocuments一次.这就是在静态构造函数中初始化它的原因.
匿名类型
var关键字创建匿名类型
1.7 结构
结构是值类型,不是引用类型.它们存储在栈中或存储为内联,其生存周期的限制与简单的数据类型一样.
结构不支持继承
对于结构构造函数的工作方式有一些区别,尤其是编译器总是提供一个无参数的默认构造函数,它是不允许替换的.
使用结构,可以置顶字段如何在内存中的布局.
结构的默认构造函数把数值字段都初始化为0,把引用类型字段初始化为null,且总是隐式给出,即使提供了其他带
参数的构造函数,也是如此,提供字段的初始值也不能绕过默认构造函数.
下面代码会产生编译错误
struct Dimensions { public double Length = 1; public double Width = 2; }
1.8 部分类
partial关键字允许把类,结构或接口放在多个文件中.一般情况下,一个类全部驻留在单个文件中.
partial class TheBigClass : TheBigBaseClass, IBigClass { public void MethodOne() { } } partial class TheBigClass : IOtherBigClass { public void MethodTwo() { } }
编译之后等价于
partial class TheBigClass : TheBigBaseClass, IBigClass,IOtherBigClass { public void MethodOne() { } public void MethodTwo() { } }
1.9 静态类
如果类中只包含静态的方法和属性,该类就是静态的.
static class StaticUtilities{ public static void HelperMethod() { }}
调用HelperMethod()不需要StaticUtilities类型的对象.直接StaticUtilities.HelperMethod();
2.0 Object类
所有的.NET类都派生自System.Object
ToString()方法---格式化
GetHashTable()方法----键值获取
Equals()方法---对象比较
Finalize()-----垃圾回收
GetType()----获取类信息
MemberwiseClone()---复制对象
飘过来学C#系列(1)之------对象和类型