简体   繁体   中英

How to pass a constant string reference to function

This post is not really about the bug in the code down below, I can myself imagine dozens of ways to solve it, its more principally related to simplicity, elegance and performance!

I had to do a very simple text parser, something like that:

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

Unfortunately it does not work that way, because the "foreach" variable "Line" is passed by reference which is not allowed.

As you might have noticed by now I am usually a C++ programmer. My thought was that passing the string as reference would be faster, cause it does not have to be copied each time.

First question: Is that assumption still valid in c#?

Second question: How can I pass a reference to that "Line" and still use "foreach" - there is no "const" in c#

Third question: Am I thinking some inappropriate C++ way and something like that would we done different in c#?

No, that's not a valid assumption. By default, C# passes strings by reference , which means a pointer is efficiently passed under the hood.

The only reason to pass a string using ref or out is if the method being called needs to modify the string and that modification needs to be reflected in the calling method. Because strings are immutable, "changing" the string in the target method actually creates a new string, which will not affect the string that was originally passed. In this case, using ref or out will cause the pointer in the calling method to be updated to point to the new, modified string.

If you aren't changing the string, then just pass the string normally and it's very efficient. I would recommend articles such as C# Concepts: Value vs Reference Types .

  1. You don't copy strings when passing them as variables, as they are reference types. You are only passing its reference.

  2. I don't think you can use a foreach loop for what you need, but you can just use a for loop.

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

Why not just split each line:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM