如何将常量字符串引用传递给函数

时间:2013-01-03 00:32:54

标签: c# string performance const ref

这篇文章并不是关于下面代码中的错误,我自己可以想象几十种方法来解决它,它主要与简单性,优雅和性能有关!

我必须做一个非常简单的文本解析器,类似的东西:

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”变量“Line”是通过引用传递的,这是不允许的。

你可能已经注意到我现在通常是一名C ++程序员。 我的想法是将字符串作为引用传递会更快,因为它不必每次都被复制。

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

第二个问题:如何传递对“Line”的引用并仍然使用“foreach” - c#中没有“const”

第三个问题:我是否正在考虑一些不恰当的C ++方式以及类似的东西,我们在c#中做了哪些不同?

3 个答案:

答案 0 :(得分:11)

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

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

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

答案 1 :(得分: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
        }
    }
    

答案 2 :(得分:0)

为什么不只是split每一行:

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