您的位置:首页 > 编程语言 > C#

C#2005 .NET3.0高级编程学习笔记————类和结构,类的数据成员,类的函数成员(方法、属性)

2008-02-01 13:06 916 查看
类和结构
类和结构实际上都是创建对象的模板,每个对象都包含数据,并提供罗勒处理和访问数据的方法。类定义了每个类对象(实例)可以包含什么数据和功能。例如一个类表示一个顾客,就可以定义字段CustomerID,FirstName,LastName和Address,以及 包含该顾客的信息,还可以定义处理存储在这些字段中的数据的功能。


class Customer




...{


public int CustomerID;


public string FirstName;


public string LastName;


public string Address;


}

结构与类的区别是它们在内存中的存储方式(类是存储在堆(heap)上的引用类型,而结构是存储在堆栈(stack)上的值类型)、访问方式和一些特性(如结构不支持继承)。较小的数据类型使用结构可提高性能。但在语法上,结构与类非常相似,主要区别是使用关键字struct代替class来声明结构


struct CustomerStruct




...{


public int CustomerID;


public string FirstName;


public string LastName;


public string Address;


}

对于类和结构,都使用关键字new来声明实例:这个关键字创建对象并对其进行初始化。


Customer myCustomer=new Customer();


CustomerStruct myCustomer2=new CustomerStruct();

类成员

类中的数据和函数称为类的成员。除了这些成员外,类还可以包含嵌套的类型(例如其他类)。类中的所有成员都可以声明为public或private。

数据成员

数据成员包含了类的数据——字段、常量和事件。数据成员可以是静态数据(与整个类相关)或实例数据(类的每个实例都有它自己的数据副本)。通常,对于面向对象的语言,类成员总是实例成员,除非用static进行了显式声明。

字段是于类相关的变量。前面的例子已经使用了Customer类中的字段,一旦实例化Customer对象,就可以使用语法Object.FieldName来访问这些字段。


Customer myCustomer=new Customer();


myCustomer.FirstName="Jerry";

常量与类的关联方式同变量与类的关联方式一样。

事件是类的成员,在发生某些行为(如改变类的字段或属性,或者进行了某种形式的用户交互操作)时,它可以让对象通知调用程序。

函数成员

函数成员提供了操作类中数据的某些功能,包括方法、属性、构造函数和终结器(finalizer)、运算符以及索引器。

方法是与某个类相关的函数,它们可以是实例方法,也可以是静态方法。实例方法处理类的某个实例,静态方法提供了更一般的功能,不需要实例化一个类。

属性是可以在客户机上访问的函数组,其访问方式与访问类的公共字段类似。

构造函数是在实例化对象时自动调用的函数。它们必须与所属类同名,且不能有返回类型。构造函数用于初始化字段的值。

终结器(析构函数)类似于构造函数,它们的名称与类相同,但前面有一个~符号。终结器在C#中用得少,因为CLR会自动进行垃圾收集。另外不可能预测什么时候调用终结器。

运算符执行的最简单的操作就是+和-。C#还允许指定把已有的运算符应用于自己的类(运算符重载)。

索引器允许对象以数组或集合的方式进行索引。

方法

方法的声明

在C#中,每个函数成员都必须与类或结构相关。正式的C#术语实际上区分了函数和方法:“函数成员”不仅包含方法,而且月包含类或结构的一些非数据成员,例如索引器、运算符、构造函数和析构函数等,甚至还有属性。

在C#中,每个方法都单独声明为public或private,不能使用public:块把几个方法定义组合起来。所有的C#方法都在类定义中声明和定义。方法的定义包括方法的修饰符、返回值的类型、方法名、输入参数的列表和方法体。


[modifiers] return_type MethodName([Parameters])




...{


Method body


}

每个参数都包括参数的类型名及在方法体中的引用名称。但如果方法体有返回值,return语句就必须与返回值一起使用,以指定出口点。


public bool Test(int x,int y)




...{


return (x==y);


}

如果方法没有返回值,就把返回类型指定为void。如果不带参数,仍需要在方法名后面写上一对空的圆括号()。此时return语句是可选的,注意方法可以包含任意多个return语句。


public bool Test(int value)




...{


if(value<0)




...{


return false;


}


return true;


}

调用方法

C#中调用方法时,必须使用圆括号。下面的例子MathTest说明了类的定义和实例化、方法的定义和调用的语法。


using System;


namespace Ling.Note.One




...{


class MainEnterpoint




...{


static void Main()




...{


Console.WriteLine("Pi is "+MathTest.GetPi());


MathTest math=new MathTest();


math.value = 30;


Console.WriteLine("Value field of "+ math.value);
Console.WriteLine("Square is"+ math.Getsquare());


}


}




class MathTest




...{


public int value;


public int Getsquare()




...{


return value*value;


}




public static double GetPi()




...{


return 3.14159;


}


}


}

给方法传递参数

参数可以通过引用或值传递给方法。在变量通过引用传递给方法时,被调用的方法得到的就是这个变量,所以在方法内部对变量进行的任何改变在方法退出后仍旧发挥作用。而如果变量是通过值传递给方法的,被调用的方法得到的是变量的一个副本,在方法退出后,对变量进行的修改会丢失。

C#中所有参数都是通过值来传递的,除非特别说明。


using System;


namespace Ling.Note.One




...{


class ParameterTest




...{


static void SomeFunction(int[] ints,int i)




...{


ints[0]=100;


i=100;


}




public static int Main()




...{


int i=0;




int[] ints=...{0,1,2,4,8};


SomeFunction(ints , i);


Console.WriteLine("i =" + i );


Console.WriteLine("ints[0] =" + ints[0] );


return 0;


}


}


}

结果是i=0,ints[0]=100。注意字符串是不同的,因为字符串是不能改变的(如果改变字符串的值,就会创建一个全新的字符串),所以字符串无法采用一般引用类型的行为方式。在方法调用中,对字符串所做的任何改变都不会影响原来的字符串。

ref参数

通过值传递变量是默认的,也可以迫使值参数通过引用方式传送给方法。需要使用ref关键字。如果把一个参数传递给方法,且这个方法的输入参数前带有ref关键字,则该方法对变量所作的任何改变都会影响原来对象的值。


static void SomeFunction(int[] ints, ref int i)




...{


ints [0] =100;


i=100;


}

在调用该方法时,还需要添加ref关键字:


SomeFunction(ints, ref i);

out关键字

C#要求变量在被引用前必须用一个初值进行初始化。尽管在把输入变量传递给函数前,可以用没有意义的值初始化它们,因为函数将使用真实、有意义的值初始化它们,但这样做是没有必要的,有时甚至会引起混乱。C#编译器使用out关键字来初始化输入参数,当在方法的输入参数前面加上out关键字时,传递给该方法的变量可以不初始化。该变量通过引用传递,在调用该方法时,还需要使用out关键字,与在定义该方法时一样


static void SomeFunction(out int i)




...{


i=100;


}




public static int Main()




...{


int i;


SomeFunction(out i);


Console.WriteLine(i);


return 0;


}

out关键字是C#中的新增内容,该关键字的引入使C#更安全,更不容易出错。

方法的重载

C#支持方法的重载——方法的几个不同签名(名称,参数个数,参数类型)的版本,为了重载方法,只需要声明同名但参数个数或类型不同的方法即可。


class Test




...{


void DoSomething(string result)




...{


.........


}


void DoSomething(int result)




...{


..........


}


}

因为C#不支持可选参数,所以需要使用方法重载来达到此目的。


class MyClass




...{


int DoSomething(int x)




...{


DoSomething(x,10);


}


int DoSomething(int x,int y)




...{


.........


}


}

两个方法不能仅在返回类型上有区别,不能仅根据参数是声明为ref还是out来区分。

属性

属性是一个方法或一对方法,在客户机代码看来,他们是一个字段。


mainForm.Height = 400;

在语法上,上面的代码类似于设置一个字段,但实际上是调用了属性访问器,它包含的代码重新设置了窗体的大小。

在C#中定义属性,可以使用下面的语法:


public string SomeProperty




...{


get




...{


return "this is the property value";


}


set




...{


.............


}


}

get访问器不带参数,且必须返回属性声明的类型。也不应为set访问器指定任何显式参数,但编译器假定它带一个参数,其类型也于属性相同,并表示为value。


private string foreName;


public string ForeName




...{


get




...{


return foreName;


}


set




...{


if(value.Length > 20)




...{


......


}


else




...{


foreName = value;


}


}


}

在属性定义中省略set访问器,就可以创建只读属性。


private string foreName;


public string ForeName




...{


get




...{


return foreName;


}


}

同样,在属性定义中省略get访问器,就可以创建只写属性。

C#允许给属性的get和set访问器设置不同的访问修饰符,在get和set访问器中,必须有一个具备属性的访问级别。

JIT编译器可以生成高度优化的代码,并在适当的时候内联代码(用内联代码代替函数调用)。如果某个方法或属性的执行代码仅是调用另一个方法,或返回一个字段,则该方法或属性肯定是内联的。(在何处内联代码的决定完全由CLR作出,无法控制)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐