科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件由C++转向C#需要注意的变化(四)

由C++转向C#需要注意的变化(四)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

在本篇文章中,我将介绍如何实现由C++到C#的飞跃。

作者:AustinLei   来源:soft6 2008年5月16日

关键字: 转向 C++ C# Windows

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

  已经有许多文章介绍过C#对C++的改进,在这里我就不再重复这些问题了。在这里,我将重点讨论由C++转向C#时最大的变化:由不可管理的环境向可管理的环境的变化。此外,我还会提出一些C#编程人员容易犯的错误供大家参考,此外,还将说明一些C#语言的能够影响编程的新功能。

  系列文章:[由C++转向C#需要注意的变化(一)(二)(三)(四)]

  在网络上读取文件

  在C++中,在网络上读取文件需要有相当的编程技巧,.NET对此提供了广泛的支持。事实上,在网络上读取文件仅仅是基础类库中Stream类的另一种应用。

  首先,为了对TCP/IP端口(在本例中是65000)进行监听,我们需要创建一个TCPListener类的实例。


   TCPListenertcpListener=newTCPListener(65000); 


  一旦创建后,就让它开始进行监听。


   tcpListener.Start(); 


  现在就要等待客户连接的要求了。


   SocketsocketForClient=tcpListener.Accept(); 


  TCPListener对象的Accept方法返回一个Socket对象,Accept是一个同步的方法,除非接收到一个连接请求它才会返回。如果连接成功,就可以开始向客户发送文件了。


   if(socketForClient.Connected)
  {
  ???


  接下来,我们需要创建一个NetworkStream类,将报路传递给constructor:


   NetworkStreamnetworkStream=newNetworkStream(socketForClient); 


  然后创建一个StreamWriter对象,只是这次不是在文件上而是在刚才创建的NetworkStream类上创建该对象:


   System.IO.StreamWriterstreamWriter=
  newSystem.IO.StreamWriter(networkStream); 


  当向该流写内容时,流就通过网络被传输给客户端。

  客户端的创建

  客户端软件就是一个TCPClient类的具体例子,TCPClient类代表连向主机的一个TCP/IP连接。


   TCPClientsocketForServer;
  socketForServer=newTCPClient("localHost",65000); 


  有了TCPClient对象后,我们就可以创建NetworkStream对象了,然后在其上创建StreamReader类:


   NetworkStreamnetworkStream=socketForServer.GetStream();
  System.IO.StreamReaderstreamReader=
  newSystem.IO.StreamReader(networkStream); 


 

[下一页]


 

现在,只要其中有数据就读取该流,并将结果输出到控制台上。


   do
  {
  outputString=streamReader.ReadLine();
  if(outputString!=null)
  {
  Console.WriteLine(outputString);
  }
  }
  while(outputString!=null);
 


  为了对这一段代码进行测试,可以创建如下一个测试用的文件:


   Thisislineone
  Thisislinetwo
  Thisislinethree
  Thisislinefour 


  这是来自服务器的输出:


   Output(Server)
  Clientconnected
  SendingThisislineone
  SendingThisislinetwo
  SendingThisislinethree
  SendingThisislinefour
  Disconnectingfromclient...
  Exiting... 


  下面是来自客户端的输出:


   Thisislineone
  Thisislinetwo
  Thisislinethree
  Thisislinefour  


  属性和元数据

  C#和C++之间一个显著的区别是它提供了对元数据的支持:有关类、对象、方法等其他实体的数据。属性可以分为二类:一类以CLR的一部分的形式出现,另一种是我们自己创建的属性,CLR属性用来支持串行化、排列和COM协同性等。一些属性是针对一个组合体的,有些属性则是针对类或界面,它们也被称作是属性目标。

  将属性放在属性目标前的方括号内,属性就可以作用于它们的属性目标。


   [assembly:AssemblyDelaySign(false)]
  [assembly:AssemblyKeyFile(".\\keyFile.snk")] 


  或用逗号将各个属性分开:


   [assembly:AssemblyDelaySign(false),
  assembly:AssemblyKeyFile(".\\keyFile.snk")] 


  自定义的属性

  我们可以任意创建自定义属性,并在认为合适的时候使用它们。假设我们需要跟踪bug的修复情况,就需要建立一个包含bug的数据库,但需要将bug报告与专门的修正情况绑定在一块儿,则可能在代码中添加如下所示的注释:


   //Bug323fixedbyJesseLiberty1/1/2005. 


 

[下一页]


 

  这样,在源代码中就可以一目了然地了解bug的修正情况,但如果如果把相关的资料保存在数据库中可能会更好,这样就更方便我们的查询工作了。如果所有的bug报告都使用相同的语法那就更好了,但这时我们就需要一个定制的属性了。我们可能使用下面的内容代替代码中的注释:


   [BugFix(323,"JesseLiberty","1/1/2005")Comment="Offbyoneerror"] 


  与C#中的其他元素一样,属性也是类。定制化的属性类需要继承System.Attribute:


   publicclassBugFixAttribute:System.Attribute 


  我们需要让编译器知道这个属性可以跟什么类型的元素,我们可以通过如下的方式来指定该类型的元素:


   [AttributeUsage(AttributeTargets.ClassMembers,AllowMultiple=true)] 


  AttributeUsage是一个作用于属性的属性━━元属性,它提供的是元数据的元数据,也即有关元数据的数据。在这种情况下,我们需要传递二个参数,第一个是目标(在本例中是类成员。),第二个是表示一个给定的元素是否可以接受多于一个属性的标记。AllowMultiple的值被设置为true,意味着类成员可以有多于一个BugFixAttribute属性。如果要联合二个属性目标,可以使用OR操作符连接它们。


   [AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface,AllowMultiple=true)] 


  上面的代码将使一个属性隶属于一个类或一个界面。

  新的自定义属性被命名为BugFixAttribute。命名的规则是在属性名之后添加Attribute。在将属性指派给一个元素后,编译器允许我们使用精简的属性名调用这一属性。因此,下面的代码是合法的:


   [BugFix(123,"JesseLiberty","01/01/05",Comment="Offbyone")] 


  编译器将首先查找名字为BugFix的属性,如果没有发现,则查找BugFixAttribute。

  每个属性必须至少有一个构造器。属性可以接受二种类型的参数:环境参数和命名参数。在前面的例子中,bugID、编程人员的名字和日期是环境参数,注释是命名参数。环境参数被传递到构造器中的,而且必须按在构造器中定义的顺序传递。


   publicBugFixAttribute(intbugID,stringprogrammer,stringdate)
  {
  this.bugID=bugID;
  this.programmer=programmer;
  this.date=date;
  }
  Namedparametersareimplementedasproperties. 

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章