2013-01-03 54 views
3

这篇文章并不是真的关于下面的代码中的错误,我可以想象它有几十种解决方法,它更主要与简单性,优雅性和性能有关!如何传递一个常量字符串参考到函数

我不得不做一个非常简单的文本解析,这样的事情:

string ParseWord(ref string Line, ref int Pos) { 
    // Inspect Line from Pos, increment Pos and return next Word 
} 

void ParseText(string[] Lines) { 
    foreach (string Line in Lines) { 
     int Pos = 0; 
     string Word; 
     while ((Word = ParseWord(ref Line, ref Pos)) != null) { 
      // Do something with Word 
     } 
    } 
} 

遗憾的是它不工作的方式,因为“的foreach”变量“线”是通过引用传递这是不允许的。如你现在可能已经注意到的,我通常是一个C++程序员。 我的想法是,传递字符串作为参考会更快,因为它不必每次都被复制。

第一个问题:这个假设在c#中仍然有效吗?

第二个问题:我如何传递到“行”的引用,并仍然使用“的foreach” - 没有“常量”,在C#

第三个问题:我在想一些不适当的C++的方式和喜欢的事那我们会在c#中完成不同的工作吗?

回答

11

不,这不是一个有效的假设。默认情况下,C#通过引用传递字符串,这意味着指针有效地在引擎盖下传递。

使用refout传递字符串的唯一原因是被调用的方法需要修改字符串,并且该修改需要反映在调用方法中。因为字符串是不可变的,所以“改变”目标方法中的字符串实际上会创建一个新字符串,这不会影响最初传递的字符串。在这种情况下,使用refout将导致调用方法中的指针更新为指向新的已修改字符串。

如果你没有改变字符串,那么只需正常传递字符串,它非常有效。我会推荐诸如C# Concepts: Value vs Reference Types之类的文章。

+0

我明白了。字符串的行为类似于值类型,但它们确实是参考的。应该有这个想法。它的基本原理与我一直将自己构建到自己的C++字符串类中的机制相同:-) –

4
  1. 将字符串作为变量传递时,不要复制字符串,因为它们是引用类型。你只是通过它的参考。

  2. 我不认为您可以使用foreach循环来满足您的需要,但您可以使用for循环。

    for (int index = 0; index < Lines.Length; index++) 
    { 
        string Line = Lines[index]; 
        int Pos = 0; 
        string Word; 
        while ((Word = ParseWord(ref Line, ref Pos)) != null) 
        { 
         // Do something with Word 
        } 
    } 
    
0

为什么不split每一行:

void ParseText(string[] Lines) 
{ 
    foreach (string Line in Lines) 
    { 
     foreach (string word in Line.Split(' ')) 
     { 
      // Do something with Word 
     } 
    } 
} 
+0

因为这只是现实中的一个简化的例子,所以解析函数会做更多的事情,并且不仅有一个。 –

相关问题