0

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?

Salah Akbari
  • 39,330
  • 10
  • 79
  • 109

2 Answers2

3

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();    
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101
  • Like this solution more than the other one because of returning StringBuilder instead of void from your extension methods. – Stefan Illner Nov 22 '18 at 11:05
1

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.

Manushin Igor
  • 3,398
  • 1
  • 26
  • 40