扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
系列文章:[由C++转向C#需要注意的变化(一)]
New的调用
在C++中,new关健字可以在堆上生成一个对象。在C#中却不是这样。对于引用类型变量而言,new关健字在堆上生成一个对象;对于结构等值类型变量而言,new关健字在栈中生成一个对象,并需要调用constructor。
事实上,我们可以不使用new关健字而在栈上生成一个结构类型的变量,但这时需要注意的是,New关健字能够初始化对象。如果不使用new,则在使用前必须手工地对结构中的所有成员进行初始化,否则在编译时会出错。
对象的初始化
usingSystem;//有二个成员变量和一个构造器的简单结构
publicstructPoint
{
publicPoint(intx,inty)
{
this.x=x;
this.y=y;
}
publicintx;
publicinty;
}
publicclassTester
{
publicstaticvoidMain()
{
Testert=newTester();
t.Run();
}
publicvoidRun()
{
Pointp1=newPoint(5,12);
SomeMethod(p1);//fine
Pointp2;//不调用new而直接创建
//编译器编译到这里时会出错,因为p2的成员变量没有被初始化
//SomeMethod(p2);
//手工对它们进行初始化
p2.x=1;
p2.y=2;
SomeMethod(p2);
}
//一个可以接受Point作为参数的方法
privatevoidSomeMethod(Pointp)
{
Console.WriteLine("Pointat{0}x{1}",
p.x,p.y);
}
}
属性
大多数的C++编程人员都希望使成员变量的属性为private,这种隐藏数据的想法促进了数据封装概念的出现,使我们能够在不改变用户依赖的接口的情况下而改变类的实现。通常情况下,我们只希望客户获取或设置这些成员变量的值。因此,C++编程人员开发出了用来存取private成员变量的存取器。
在C#中,属性是类的第一级成员。对于客户而言,属性看起来象一个成员变量。对于类的实现者而言,它看起来更象是方法。这种设计很巧妙,既可以实现数据的隐藏和封装,又可以使客户很方便地访问成员变量。
我们可以在Employee类中添加一个Age属性,使客户可以很方便地获取和设置员工年龄这个类的成员:
publicintAge
{
get
{
returnage;
}
set
{
age=value;
}
}
关健字value可以被属性隐性地使用。如果编写如下的代码:
Fred.Age=17;
编译器将会把值17传递给value。
通过只采用Get而不采用Set,我们可以为YearsServed创建一个只读的属性:
publicintYearsServed
{
get
{
returnyearsServed;
}
}Accessors的使用
privatevoidRun()
{
EmployeeFred=newEmployee(25,101,7);
Console.WriteLine("Fred''sage:{0}",
Fred.Age);
Fred.Age=55;
Console.WriteLine("Fred''sage:{0}",
Fred.Age);
Console.WriteLine("Fred''sservice:{0}",
Fred.YearsServed);
//Fred.YearsServed=12;//是不被允许的
}
我们可以通过属性获取Fred的年龄,也可以使用这一属性设置年龄。我们虽然可以访问YearsServed属性获得它的值,但不能设置值。如果没有注释掉最后一行的代码,在编译时就会出错。
如果以后决定从数据库中获取Employee的年龄,我们就只需要改变存取器的实现,而客户不会受到任何影响。
数组
C#提供了一个数组类,它比C/C++中传统的数组更智能化。例如,在C#中写数组时不会超出边界。此外,数组还有一个更智能的伙伴—ArrayList,可以动态地增长,管理对数组大小不断变化的需求。
C#中的数组有三种形式:一维数组、多维均匀数组(象C++中传统的数组那样)、非均匀数组(数组的数组)。我们可以通过下面的代码创建一维数组:
int[]myIntArray=newint[5];
另外,还可以以如下的方式对它进行初始化:
int[]myIntArray={2,4,6,8,10};
我们可以通过如下方式创建一个4×3的均匀数组:
int[,]myRectangularArray=newint[rows,columns];
我们可以按如下方式对该数组进行初始化:
int[,]myRectangularArray=
{
{0,1,2},{3,4,5},{6,7,8},{9,10,11}
};
由于非均匀数组是数组的数组,因此,我们只能创建一维非均匀数组:
int[][]myJaggedArray=newint[4][];
然后再创建内部的每个数组:
myJaggedArray[0]=newint[5];
myJaggedArray[1]=newint[2];
myJaggedArray[2]=newint[3];
myJaggedArray[3]=newint[5];
由于数组是由继承System.Array对象而得到的,因此,它们带有许多包括Sort、Reverse在内的许多有用的方法。
索引器
我们可以创建象数组一样的对象。例如,我们可以创建一个显示一系列字符串的列表框,可以把列表框当作一个数组,使用一个索引就可以很方便地访问列表框中的内容。
stringtheFirstString=myListBox[0];
stringtheLastString=myListBox[Length-1];
这是通过索引器完成的。索引器在很大程度上象一个属性,但支持索引操作的语法。图4显示了一个后面跟着索引操作符的属性,图5显示如何完成一个很简单的ListBox类并对它进行索引:
界面
软件界面是二种对象之间如何进行交互的契约。如果一个对象发布了一个界面,就等于向所有可能的客户声明:我支持下面的方法、属性、事件和索引器。
C#是一种面向对象的语言,因此这些契约被封装在一个被称作界面的实体中,界面定义了封装着契约的引用型类型的对象。从概念上来讲,界面与抽象类非常相似,二者的区别是抽象类可以作为一系列衍生类的基础类,界面则是与其他继承树结合在一起的。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者