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

本文关键字:函数 引用 字符串 常量 | 更新日期: 2023-09-27 17:50:23

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

我必须做一个非常简单的文本解析器,就像这样:

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#中会做得不同吗?

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

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

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

如果你不改变字符串,那么就正常传递字符串,这是非常有效的。我推荐《c#概念:值与引用类型》等文章。

  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
        }
    }
    

为什么不把每一行分开呢:

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