user9945420
user9945420

Reputation:

change value by reference when using an extension method

I want to create an error message string. It should contain multiple hints to fix the errors.

First I created something like this

string errorMessage = string.Empty;

if (1 == 1)
    errorMessage += "- hint 1\n";

if (2 == 2)
    errorMessage += "- hint 2\n";

if (3 == 3)
    errorMessage += "- hint 3";

// do something with errorMessage

And I thought about cleaning it up. I created an extension method

public static void AppendIf(this string s, bool condition, string txtToAppend)
{
    if (condition)
        s += txtToAppend;
}

And call it within my class

string errorMessage = string.Empty;

errorMessage.AppendIf(1 == 1, "- hint 1\n");
errorMessage.AppendIf(2 == 2, "- hint 2\n");
errorMessage.AppendIf(3 == 3, "- hint 3");

// do something with errorMessage

But errorMessage stays empty. I thought this acts like the ref keyword so what is wrong with my extension method?

Upvotes: 0

Views: 69

Answers (2)

Manushin Igor
Manushin Igor

Reputation: 3689

You could not use this ref modifier, please check compiler feature request.

However you can get the same result by using the StringBuilder type:

public static void AppendIf(this StringBuilder s, bool condition, string txtToAppend)
{
    if (condition)
        s.Append(txtToAppend);
}

So, your code will be:

string errorMessage = new StringBuilder();

errorMessage.AppendIf(1 == 1, "- hint 1\n");
errorMessage.AppendIf(2 == 2, "- hint 2\n");
errorMessage.AppendIf(3 == 3, "- hint 3");

NB: please avoid executing code like str += anotherStr; inside the loop, because this method has O(N^2) complexity, where N is count of chars. Please check details in this question.

Upvotes: 1

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34189

string is immutable, which means that it creates a new string every time you append to it, so it is impossible.

However, you can use StringBuilder to achieve it:

public static class StringBuilderExtensions
{
    public static StringBuilder AppendLineIf(this StringBuilder builder, bool condition, string line)
    {
        // validate arguments
        if (condition) 
            builder.AppendLine(line);
        return builder;            
    }

    public static StringBuilder AppendIf(this StringBuilder builder, bool condition, string line)
    {
        // validate arguments
        if (condition) 
            builder.Append(line);
        return builder;            
    }
}

StringBuilder builder = new StringBuilder();
builder.AppendLineIf(1 == 1, "- hint 1");
builder.AppendLineIf(2 == 2, "- hint 2");
builder.AppendLineIf(3 == 3, "- hint 3");

string result = builder.ToString();
// do something with result

You can also chain these calls, if it looks better for you:

string result = new StringBuilder()
    .AppendLineIf(1 == 1, "- hint 1")
    .AppendLineIf(2 == 2, "- hint 2")
    .AppendLineIf(3 == 3, "- hint 3")
    .ToString();    

Upvotes: 3

Related Questions