正在阅读:由C++转向C#需要注意的变化(二)由C++转向C#需要注意的变化(二)

2004-11-17 09:59 出处:CSDN 作者:AustinLei 责任编辑:linjixiong

  引言:每隔10年左右,编程人员就需要花费大量的时间和精力去学习新的编程技术。在80年代是Unix和C,90年代是Windows和C++,现在又轮到了微软的.NETFramework和C#。尽管需要学习新的技术,但由此带来的好处却远高于付出的劳动。幸运的是,使用C#和.NET进行的大多数工程的分析和设计与在C++和Windows中没有本质的变化。在本篇文章中,我将介绍如何实现由C++到C#的飞跃。

  系列文章:[由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#是一种面向对象的语言,因此这些契约被封装在一个被称作界面的实体中,界面定义了封装着契约的引用型类型的对象。从概念上来讲,界面与抽象类非常相似,二者的区别是抽象类可以作为一系列衍生类的基础类,界面则是与其他继承树结合在一起的。



察看评论详细内容 我要发表评论
作者笔名简短内容 发表时间
:

关注我们

最新资讯离线随时看 聊天吐槽赢奖品