科技行者

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

知识库

知识库 安全导航

至顶网软件频道基础软件由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#需要注意的变化(一)(二)(三)(四)(五)]

  只发现方法

  我们可能会只关心方法,而不关心域、属性等,为此,我们需要删除如下的对GetMembers的调用:


   MemberInfo[]mbrInfoArray=
  theType.GetMembers(BindingFlags.LookupAll); 


  然后添加调用GetMethods的语句:


   mbrInfoArray=theType.GetMethods(); 


  现在,输出中就只剩下方法了。


   Output(excerpt)
  BooleanEquals(System.Object)isaMethod
  System.StringToString()isaMethod
  System.StringCreateQualifiedName(System.String,System.String)
  isaMethod
  System.Reflection.MethodInfoget_EntryPoint()isaMethod 


  发现特定的成员
  最后,为了进一步地缩小范围,我们可以使用FindMembers方法来发现某一类型的特定的方法。例如,在下面的代码中,我们可以只搜索以“Get”开头的方法。


   publicclassTester
  {
  publicstaticvoidMain()
  {
  //检查一个单一的对象
  TypetheType=Type.GetType("System.Reflection.Assembly");
  //只获取以Get开头的成员
  MemberInfo[]mbrInfoArray
  theType.FindMembers(MemberTypes.Method,
  BindingFlags.Default,
  Type.FilterName,"Get*");
  foreach(MemberInfombrInfoinmbrInfoArray)
  {

  Console.WriteLine("{0}isa{1}",
  mbrInfo,mbrInfo.MemberType.Format());
  }
  }
  }


  其输出的一部分如下所示:


   System.Type[]GetTypes()isaMethod
  System.Type[]GetExportedTypes()isaMethod
  System.TypeGetType(System.String,Boolean)isaMethod
  System.TypeGetType(System.String)isaMethod
  System.Reflection.AssemblyNameGetName(Boolean)isaMethod
  System.Reflection.AssemblyNameGetName()isaMethod
  Int32GetHashCode()isaMethod
  System.Reflection.AssemblyGetAssembly(System.Type)isaMethod
  System.TypeGetType(System.String,Boolean,Boolean)isaMethod 


  动态调用

  一旦发现一个方法,可以使用映射的方法调用它。例如,我们可能需要调用System.Math中的Cos方法(返回一个角的余弦值)。为此,我们需要获得System.Math类的类型信息,如下所示:


   TypetheMathType=Type.GetType("System.Math"); 


  有了类型信息,我们就可以动态地加载一个类的实例:


   ObjecttheObj=Activator.CreateInstance(theMathType); 


  CreateInstance是Activator类的一个静态方法,可以用来对对象进行初始化。

  有了System.Math类的实例后,我们就可以调用Cos方法了。我们还需要准备好一个定义参数类型的数组,因为Cos只需要一个参数(需要求余弦值的角度),因此数组中只需要有一个成员。我们将在数组中赋予一个System.Double类型的Type对象,也就是Cos方法需要的参数的类型:


   Type[]paramTypes=newType[1];
  paramTypes[0]=Type.GetType("System.Double"); 


  现在我们就可以传递方法的名字了,这个数组定义了Type对象中GetMethod方法的参数的类型:


   MethodInfoCosineInfo=
  theMathType.GetMethod("Cos",paramTypes); 


  我们现在得到了MethodInfo类型的对象,我们可以在其上调用相应的方法。为此,我们需要再次在数组中传入参数的实际值:


   Object[]parameters=newObject[1];
  parameters[0]=45;
  ObjectreturnVal=CosineInfo.Invoke(theObj,parameters); 


  需要注意的是,我创建了二个数组,第一个名字为paramTypes的数组存储着参数的类型,第二个名字为parameters的数组保存实际的参数值。如果方法需要二个参数,我们就需要使这二个数组每个保持二个参数。如果方法不需要参数,我们仍然需要创建这二个数组,只是无需在里面存储数据即可。


   Type[]paramTypes=newType[0]; 


  尽管看起来有点奇怪,但它是正确的。下面是完整的代码:

  映射方法的使用


   usingSystem;
  usingSystem.Reflection;publicclassTester
  {
  publicstaticvoidMain()
  {
  TypetheMathType=Type.GetType("System.Math");
  ObjecttheObj=Activator.CreateInstance(theMathType);
  //只有一个成员的数组
  Type[]paramTypes=newType[1];
  paramTypes[0]=Type.GetType("System.Double");

  //获得Cos()方法的信息
  MethodInfoCosineInfo=
  theMathType.GetMethod("Cos",paramTypes);

  //将实际的参数填写在一个数组中
  Object[]parameters=newObject[1];
  parameters[0]=45;
  ObjectreturnVal=CosineInfo.Invoke(theObj,parameters);
  Console.WriteLine(
  "Thecosineofa45degreeangle{0}",returnVal);

  }
  }
 


  结论

  尽管有许多小错误等着C++编程人员去犯,但C#的语法与C++并没有太大的不同,向新语言的转换是相当容易的。使用C#的有趣的部分是使用通用语言运行库,这篇文章只能涉及几个重点问题。CLR和.NETFramework提供了对线程、集合、互联网应用开发、基于Windows的应用开发等方面提供了更多的支持。语言功能和CLR功能之间的区分是非常模糊的,但组合在一起就是一种功能非常强大的开发工具了。


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

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

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