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

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

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

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

第三个问题:我是否在想一些不合适的 C++ 方式以及我们在 C# 中会做不同的事情吗?

4

3 回答 3

11

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

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

如果您不更改字符串,则只需正常传递字符串即可,它非常有效。我会推荐诸如C# Concepts: Value vs Reference Types之类的文章。

于 2013-01-03T00:37:37.300 回答
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
        }
    }
    
于 2013-01-03T00:37:41.600 回答
0

为什么不只拆分每一行:

void ParseText(string[] Lines)
{
    foreach (string Line in Lines)
    {
        foreach (string word in Line.Split(' '))
        {
            // Do something with Word
        }
    }
}
于 2013-01-03T00:38:28.603 回答