C#程序中Bug的快速修复方法

2016-02-19 13:46 31 1 收藏

下面图老师小编要向大家介绍下C#程序中Bug的快速修复方法,看起来复杂实则是简单的,掌握好技巧就OK,喜欢就赶紧收藏起来吧!

【 tulaoshi.com - 编程语言 】

  本文将为大家介绍一下如何对C#程序Bug修复的快速方法。.NET Framework中包含许多工具可以用来更快、更容易地编写正确的程序。但我们得面临这样的情况:出现bugs。不管程序多么简单,程序员都可能出错。

  根据我的经验,大多数程序的bugs出现在程序员之间的接口:当一个程序员编写的代码被另一个程序员调用时。不知何故,调用者破坏了代码编写时做的假设。是谁的过错呢?这并不要紧,更重要的是你能多快修好它?下面这些技巧将帮你在程序投入使用前更快地发现并解决这些问题。最终,这些技巧会帮你诊断任何的确在使用中出现的问题。

  测试假设条件

  测试假设条件是构建正确的程序最重要的一个方法。在你写一个函数时,你应该考虑并确定你对那个函数做了什么样的假设。你应该问自己以下这些问题:

  1. 当这个函数被调用时,这个对象必须是怎样的(对象初试化,某个内在变量值)?

  2. 当这个函数存在时,这个对象将会怎样(仍是#1,但包括该函数的副作用)?

  3. 该函数的任何参数必须是怎样的(允许空值吗,输入值的范围是什么)?

  4. 返回值必须是怎样的?

  一旦你问了自己这四个问题并作出回答后,把答案放到代码中。

  在C#中,用System.Diagnostics.Debug类的Assent方法来表示:

以下是引用片段:
public bool ProcessIterations (int numIters)
  {
  Debug.Assert (numIters  0,
  "ProcessIterations.",
  "Iterations must be more than 0");
  // More code...

  该代码片段执行了numiters参数必须大于零这样一个假设。如果你用一个无效的参数调用processiterations,该assert被触发。这时候,程序停止运行并通知用户出现的错误。声明(assertions)只被编译到debug 版本中的程序,所以它们不影响生产情况中的性能。

  为什么用这种方法? 运用这种技巧可以确保很快地发现对你的类的方法未预料地使用。然后,或者调用者修改他的代码,或者要求在你的类的行为(behavior)中修改。

  验证完整性

  一个C# 程序中的大多数函数都是一个对象上的实例方法。对任何对象的有效状态都有暗示的假设。当一个公有的方法被调用时,你应该确保那些暗示的假设经过了测试。C# 的条件编译特征使这一点很容易实现。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  首先,写一个私用的函数来测试对象的完整性。你在这么做时,将该方法标为“conditional”: [Conditional ("DEBUG")]

以下是引用片段:
  private void ImOK ()
  {
  Debug.Assert (this != null,
  "Testing Object State",
  "this cannot be null");
  // More here.
  }

  然后,在每个公有的方法中,调用ImOK方法:

以下是引用片段:
public bool ProcessIterations (int numIters)
  {
  ImOK ();
  Debug.Assert (numIters  0,
  "ProcessIterations.",
  "Iterations must be more than 0");}

  在发布(Release)版本中,编译器自动取消对ImOK 的调用。

  为什么用这种方法?运用该技巧,你可以快速发现任何你的对象状态变得无效的情况。

  运用debug 和Trace 输出

  打印诊断消息可以帮你确定你的程序是怎么出错的。你需要知道当触发一个Assert时,发生了什么情况;你也通常需要知道在这之前发生了什么。知道这些的最好的方式就是运用你的代码,这样你就可以很容易地看到在出现bug前,调用了什么函数。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  在生成调试输出时,.net Framework有一些新的功能可以用。System.Diagnostic.Debug类可以让你格式化调试输出,并能很容易地创建不同的类或级别的调试输出。下面是我喜欢用的一些指导方针。

  首先,在你的程序中为每个类建一个traceswitch对象:

以下是引用片段:
public class MyClass
  {
  private static TraceSwitch
  myClassSwitch = new TraceSwitch
  ("MyClassSwitch", "Controls the 
  debug output of MyClass");}

  然后,用WriteIf() 和 WriteLineIf() 方法来记录任何你觉得有助于你跟踪你的程序的信息:

以下是引用片段:
public bool ProcessIterations (int
  numIters)
  {
  WriteLineIf
  (myClassSwitch.TraceInfo,
  "Entering ProcessIterations",
  "CallTrace");
  ImOK ();
  Debug.Assert (numIters  0,
  "ProcessIterations.",
  "Iterations must be more than 0");}

  我更喜欢用WriteLineIf(),它可以打印出错误消息以及错误种类。第一个参数包含一个用于调试开关的值,可以让你控制打印什么级别的输出。

  System.Diagnostics.Trace 的运用同Debug的用法完全一样。 不同的地方是,Debug只编译到Debug版本中,而Trace语句编译到Debug和Release版本中。因此,运用Trace语句应更谨慎。将Trace语句用到可以在编程实战中帮你发现bugs或捕获使用特征的代码中。

  为什么用这种方法? 运用这些方法可以让你知道代码执行的顺序。这有助于你确定在程序出错前有何动作(actions)。

  动态地控制输出

  这些新的.NET Framework类的最大的好处是通过编辑一个配置文件,你可以改变任何跟踪开关(trace switch) 的级别。在应用程序目录中建一个XML文件,该文件的名字与你的程序的名字相同,扩展名为“.config”。例如,如果你的程序是myApp.exe,就建一个myApp.exe.config。你可以用这个文件来设置你的跟踪开关的值。比如下面的文件:

以下是引用片段:
?xml version="1.0"?
configuration
system.diagnostics
switches
add name="MyClassSwitch" 
value="4" /
/switches
/system.diagnostics
/configuration

  该文件把MyClassSwitch的值设置为4,符合“Info”的设置。仅通过编辑这个config文件,你就可以改变你的程序中任何开关的级别。

  为什么用这种方法?通过运用多个开关和创建适当的config文件,你可以改变记录输出,集中精力到你关心的那些元素上。

  设置你的listeners

  .NET Framework有一个代表接收Debug、Assert和Trace输出的对象的Listeners集合。默认情况下,你的应用程序有一个单一的DefaultTraceListener。这个listener忽略Debug和Trace输出,显示一个Assert消息的对话框。你可以添加项目到这个集合,或从这个集合中删除项目。已为你创建好的两项是TextWriterTraceListener和EventLogTraceListener。TextWriterTraceListener把消息写到一个流(stream)中,EventLogTraceListener把消息写到一个EventLog中。EventLog可以让你把你的程序的调试和跟踪消息写到系统事件日志记录中。

  我喜欢为所有程序建一个调试日志文件:

以下是引用片段:
static void Main ()
  {
  Debug.Listeners.Add (
  New TextWriteTraceListener
  ("MyLog.log");
  // etc.

  为什么用这个方法? 该技巧可以让你控制在哪里用调试和跟踪语句。

  在你发现bugs时,用这些技巧.

  坦白地说,在开始写代码时,没有人用所有这些技巧。实际上,当我们努力想发现那些重大bugs的原因时我们通常添加这些语句。在你陷入那种困境时,尝试以下方法:

  1. 当你创建类时,通常为每个类建一个跟踪开关。

  2. 通常为每个类建一个验证函数。

  3. 当你要诊断错误的行为时,添加其它的跟踪和调试语句。确信把这些变化保留在代码中。我发现的最常见的错误之一就是:当程序员想找到bugs时,他们添加许多跟踪和调试语句来发现错误。然后,一旦他们找到了他们查找的错误,他们就把这些语句删掉。

  这些工具会帮你发现并修理bugs,就看你用不用它们了。

  本文将为大家介绍一下如何对C#程序Bug修复的快速方法。.NET Framework中包含许多工具可以用来更快、更容易地编写正确的程序。但我们得面临这样的情况:出现bugs。不管程序多么简单,程序员都可能出错。

  根据我的经验,大多数程序的bugs出现在程序员之间的接口:当一个程序员编写的代码被另一个程序员调用时。不知何故,调用者破坏了代码编写时做的假设。是谁的过错呢?这并不要紧,更重要的是你能多快修好它?下面这些技巧将帮你在程序投入使用前更快地发现并解决这些问题。最终,这些技巧会帮你诊断任何的确在使用中出现的问题。

  测试假设条件

  测试假设条件是构建正确的程序最重要的一个方法。在你写一个函数时,你应该考虑并确定你对那个函数做了什么样的假设。你应该问自己以下这些问题:

  1. 当这个函数被调用时,这个对象必须是怎样的(对象初试化,某个内在变量值)?

  2. 当这个函数存在时,这个对象将会怎样(仍是#1,但包括该函数的副作用)?

  3. 该函数的任何参数必须是怎样的(允许空值吗,输入值的范围是什么)?

  4. 返回值必须是怎样的?

  一旦你问了自己这四个问题并作出回答后,把答案放到代码中。

  在C#中,用System.Diagnostics.Debug类的Assent方法来表示:

以下是引用片段:
public bool ProcessIterations (int numIters)
  {
  Debug.Assert (numIters  0,
  "ProcessIterations.",
  "Iterations must be more than 0");
  // More code...

  该代码片段执行了numiters参数必须大于零这样一个假设。如果你用一个无效的参数调用processiterations,该assert被触发。这时候,程序停止运行并通知用户出现的错误。声明(assertions)只被编译到debug 版本中的程序,所以它们不影响生产情况中的性能。

  为什么用这种方法? 运用这种技巧可以确保很快地发现对你的类的方法未预料地使用。然后,或者调用者修改他的代码,或者要求在你的类的行为(behavior)中修改。

  验证完整性

  一个C# 程序中的大多数函数都是一个对象上的实例方法。对任何对象的有效状态都有暗示的假设。当一个公有的方法被调用时,你应该确保那些暗示的假设经过了测试。C# 的条件编译特征使这一点很容易实现。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  首先,写一个私用的函数来测试对象的完整性。你在这么做时,将该方法标为“conditional”: [Conditional ("DEBUG")]

以下是引用片段:
  private void ImOK ()
  {
  Debug.Assert (this != null,
  "Testing Object State",
  "this cannot be null");
  // More here.
  }

  然后,在每个公有的方法中,调用ImOK方法:

以下是引用片段:
public bool ProcessIterations (int numIters)
  {
  ImOK ();
  Debug.Assert (numIters  0,
  "ProcessIterations.",
  "Iterations must be more than 0");}

  在发布(Release)版本中,编译器自动取消对ImOK 的调用。

  为什么用这种方法?运用该技巧,你可以快速发现任何你的对象状态变得无效的情况。

  运用debug 和Trace 输出

  打印诊断消息可以帮你确定你的程序是怎么出错的。你需要知道当触发一个Assert时,发生了什么情况;你也通常需要知道在这之前发生了什么。知道这些的最好的方式就是运用你的代码,这样你就可以很容易地看到在出现bug前,调用了什么函数。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  在生成调试输出时,.net Framework有一些新的功能可以用。System.Diagnostic.Debug类可以让你格式化调试输出,并能很容易地创建不同的类或级别的调试输出。下面是我喜欢用的一些指导方针。

  首先,在你的程序中为每个类建一个traceswitch对象:

以下是引用片段:
public class MyClass
  {
  private static TraceSwitch
  myClassSwitch = new TraceSwitch
  ("MyClassSwitch", "Controls the 
  debug output of MyClass");}

  然后,用WriteIf() 和 WriteLineIf() 方法来记录任何你觉得有助于你跟踪你的程序的信息:

来源:https://www.tulaoshi.com/n/20160219/1605186.html

延伸阅读
.NET将关于多线程的功能定义在System.Threading名字空间中。因此,要使用多线程,必须先声明引用此名字空间(using System.Threading;)。 即使你没有编写多线程应用程序的经验,也可能听说过“启动线程”“杀死线程”这些词,其实除了这两个外,涉及多线程方面的还有诸如“暂停线程”“优先级”“挂起线程”“恢复线程”等等。下面将一个...
标签: 美容护肤
晒后皮肤缺水干燥 1 表现:紫外线让表皮细胞迅速脱水,导致干燥泛红起皮等症状,肌肤失去光泽变得紧绷,甚至有皮屑出现手感也变得粗糙。 对策:需要给肌肤补充流失的水分,可敷一贴晒后修复面膜,既能镇静肌肤,又能补充水分;或者用化妆棉浸满有舒缓功能的化妆水敷在皮肤不适处来缓解肌肤压力;洗澡后趁着毛孔彻底打开选用含有芦荟凝胶和海藻...
欢迎来到C#的奇妙天空,在这里,希望你能获得你想获得的东西,.我们真诚希望能给你带来巨大的帮助,带你进入另外一个广阔的空间。 Come on. Follow me and then U can Win! 同Linux下的Gnu C ++ 工具中的gdb类似,C#提供了一个命令行调试程序"Cordbg.exe",通过这个程序你可以很轻松的调试你的C#应用程序,本文在下面不可能完全给...
在编写多线程程序时无可避免会碰到线程的同步问题。什么是线程的同步呢? 举个例子:假如在一个公司里面有一个变量记录某人T的工资count=100,有两个主管A和B(即工作线程)在早一些时候拿了这个变量的值回去 ,过了一段时间A主管将T的工资加了5块,并存回count变量,而B主管将T的工资减去3块,并存回count变量。好了,本来T君可以得到102块...
标签: Web开发
C#实现文件拖放并打开文件 需要知道的ListBox的两个事件:当您在控件的边界内拖动对象时,便会发生 DragEnter 事件;该事件用于确 定当前拖动的对象是不是您要放到控件上的对象。 在将一个或多个文件拖到控件上时,需要处理此事件。 这使 得在将对象拖到控件上方时,能够根据所拖动的对象显示相应的图标。 将拖动的对象释放到控件上时,...

经验教程

613

收藏

12
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部