2013-04-23 169 views
5

更好假设我有以下组中的静态函数这是在这种情况下,返回或ref

在这里,我通过引用发送的变量:

public static void ProcessEmailMessage(ref string HTML) 
     { 
      ModifyLinks(ref HTML); 
      AddFakeImage(ref HTML); 
     } 

     public static void ModifyLinks(ref string HTML) 
     { 
      //modify HTML links 
     } 


     public static void AddFakeImage(ref string HTML) 
     { 
      //adds an image to the HTML 
     } 

和在这里,我通过值

发送的可变
public static string ProcessEmailMessage(string HTML) 
     { 
      HTML = ModifyLinks(HTML); 
      HTML = AddFakeImage(HTML); 
      return HTML; 
     } 

     public static string ModifyLinks(string HTML) 
     { 
      //modify HTML links 
      return HTML; 
     } 


     public static string AddFakeImage(string HTML) 
     { 
      //adds an image to the HTML 
      return HTML; 
     } 

哪一个更有意义,2是否有任何性能差异?

+2

** b)** ......... – I4V 2013-04-23 17:42:23

回答

8

如果可能,避免使用out和ref参数。

使用ref和out参数的方法更难以使用,您需要声明一个变量来保存结果,并且语义有点难以理解。性能差异(如果有的话)可以忽略不计。

在这种情况下,Visual Studio中的代码分析可能会发出警告。

有关更详细的说明,请参阅http://msdn.microsoft.com/en-us/library/ms182131

+1

指向外部文档的链接很好,但您应在此处包含摘要。如果外部链接断开,那么SO答案仍然有用。 – cdhowie 2013-04-23 17:44:21

+0

@cdhowie:感谢您指出这一点。我已经编辑了这篇文章以包含更多的摘要。 – DeCaf 2013-04-23 17:48:32

2

使用ref时可能会有更多的性能问题,因为在分配给变量时,这相当于额外的间接级别。但是,这种差异可能是微不足道的。

我宁愿返回一个字符串的形式,这更说明了什么是真正发生的事情,并允许您链方法调用在一起,如果你喜欢:

return AddFakeImage(ModifyLinks(HTML)); 

随着ref形式你强制调用代码来声明一个变量,他们可能不需要。这妨碍了可读性并增加了无意义的样板代码的发生率。

+0

从技术上讲,在这两种情况下都声明了一个变量,这只是程序员是否需要知道的一个问题。在你给出的代码示例中存在一个隐式的未命名局部变量。现在,这就是说,不必知道这件事是很好的,但从性能的角度来看,它没有什么不同。 – Servy 2013-04-23 17:43:58

+0

@Servy JIT编译时会有一个寄存器,但是我已经显示的代码示例将声明比原始代码更少的本地代码。缩写的IL将是'ldarg.0;呼叫;呼叫; RET;'。所以不,没有“附加变量”,至少在翻译成本地代码之前是没有的。 (变量实际上并不存在于本地代码中,只是寄存器和内存位置。变量的概念比本地代码更高级。) – cdhowie 2013-04-23 17:46:00

+0

在这两种情况下,无论是否存在命名本地,实际的处理器指令级别都很可能会被注册,但如果不可能的话,两者都可能被存储在内存中的某个位置。 – Servy 2013-04-23 17:47:57

1

两者之间的性能差异可以忽略不计。这几乎完全是语法优先的问题。

标准约定将涉及返回一个新的字符串,而不是修改通过引用传递的参数。有几种情况下使用起来更方便(即,当您没有命名变量时;例如,当您想传入方法或属性的返回值而不是字段时)。

1

没什么区别,但我会用“回归”去。尽可能避免使用“ref”。

的原因是你不会有路过另一个调用的结果之前声明一个变量,你可以调用链:

与裁判:

string modifyMe = GetMeString(); 
ModifyLints(ref modifyMe); 
AddFakeImage(ref modifyMe); 

相比返回:

string result = AddFakeImage(ModifyLinks(GetMeString())); 
1

如果您需要返回多个对象,请使用ref/out,如果您可以使用return执行此操作,只需返回一个obj等,使用return
ref使您的代码不必要地模糊,并产生在这种情况下不必要的写入开销。
你应该总是尽量保持你的代码简单和可视化。

1

我喜欢的东西像一个制造商,其作用:。

新EmailMessageProcessor(HTML).WithModifiedLinks()WithFakeImages()。

所以没有参考参数,一切都被封装了。