C# 默认为使用ref关键字传递引用类型
我与一位默认使用ref关键字传递引用类型(如StringBuilder、string和MemoryStream)的开发人员一起工作。无论是否需要实际更改引用本身,它们都会这样做C# 默认为使用ref关键字传递引用类型,c#,C#,我与一位默认使用ref关键字传递引用类型(如StringBuilder、string和MemoryStream)的开发人员一起工作。无论是否需要实际更改引用本身,它们都会这样做 public void ExampleMethod(ref MemoryStream ms) { byte b=ms.ReadByte(); ... // No changing of actual ms reference such as: ms=new MemoryStream(); }
public void ExampleMethod(ref MemoryStream ms)
{
byte b=ms.ReadByte();
...
// No changing of actual ms reference such as: ms=new MemoryStream();
}
几乎总是,这些方法只使用对象并返回,而不以任何方式更改引用。对于不可变类型即字符串,这有时是必要的,但为什么对于可变类型
对我来说,这有一点“代码味道”,因为它可能会导致不太可维护的代码,因为它比它真正需要的更宽容
然而,对于我来说,这是一件非常严肃的事情吗?我最初的感觉是肯定的,但也许这太迂腐了?也许你可以问那个开发人员为什么这么做。。。 也许他(错误地)认为这更有效?也许开发者是C++开发者,他认为使用REF与使用C++中的指针类似?p> 如果他来自C++背景,我会问开发者为什么这么做,并向他解释这完全不是必要的。它不会提高性能,而是为方法提供了不同的语义,因为它允许更改引用,并且只有在确实需要方法更改引用时才应该使用ref关键字
我不认为这是迂腐的。即使是有经验的开发人员也不知道他所使用的新语言的所有细节。当你向他解释的时候,他会学到一些新东西,也许他会感激的 关键字
ref
仅在修改值类型时有用(从ValueType
派生的任何内容)。值类型包括int
、byte
、char
、struct
、float
等。使用ref
作为对象引用或类,例如Stream
子体或StringBuilder
没有意义,肯定是一种代码味道
我唯一一次看到有必要将
StringBuilder
引用作为ref
传递是在将字符串值编组到Win32和从Win32编组字符串值时。我不认为这太迂腐,因为开发人员可能误解了“ref”关键字的用途。它应该在绝对必要的地方使用,表示该方法将保证或很可能与其他方法交换引用,而不仅仅是为了好玩
更新至于如何沟通……嗯,可能在某种程度上取决于他为什么把裁判放在所有事情上的动机。如果他认为这将提高性能,那么使用StopWatch.StartNew()执行一个小程序,并将内容传递到一个有无ref的方法中。我没有尝试过,但我认为性能差异可能在于创建一个新的引用,这应该非常小
除此之外,功能应按预期使用并表达意图。当我看到一个带有ref或out参数的方法时,我希望它们要么完全更改传入的实例,要么该方法分别初始化传入的对象。不将这些关键字用于这些目的只是一种让其他程序员感到困惑的方式,方法调用中充斥着不必要的关键字,并可能对所使用的API设定错误的期望。这看起来像是一种误解;向方法传递引用时需要
ref
关键字。您应该询问开发人员情况是否如此
在不需要时使用ref
关键字的唯一原因是允许稍后更改方法以替换对象。当然,这只应该用在你真正期望你会需要它的地方。通常,您应该只针对当前的需求编写代码,而不是针对您可以想象的所有可能的需求
如果发现由于任何原因不需要的ref
,应将其从代码中删除。遵循封装原则,该方法对参数值的处理能力不应超过其需要
通常,很少使用
ref
关键字。在大多数情况下,可以使用更面向对象的方法。出于性能原因,它有时与值类型一起使用,比如在Double.TryParse
方法中,但从未真正与引用类型一起使用。这绝对值得一提。我已经见过很多次了,这总是因为开发人员不理解类型系统——这是编写正确和可维护代码的关键部分
我会找到一个例子,在这个例子中,这显然是不必要的,但是他们希望更改对象本身的内容——理想的情况是添加到StringBuilder
中。然后礼貌地问他们为什么选择使用ref
修饰语。指出它在不使用的情况下也同样有效
请随时将它们提交给我的和我的。我想topicstarter知道这一点。:)他的问题有点不同@Mike,在某些特定的合理情况下(我同意这种情况不太常见),在引用类型上使用ref是完全合理的。经典的例子是交换实际引用的交换函数。在某些情况下,对引用类型使用ref/out绝对有意义。一个例子是
Dictionary.TryGetValue(key,out value)
如果我将对变量a的引用传递到函数中,我传递的是一个内存“位置”,它可能会被更新以指向其他对象。我的想法是,本质上,我并没有改变变量A,而是改变它所指向的。我必须同意阿什和乔恩的观点,我的错@Frederik,是的,它们来自C++背景。我想你对贝莱夫的看法可能是对的