Search code examples
c#stringbuilder

Appending only existing string/values in StringBuilder using extension


I have this method, this works as expected, it does not insert <string, value> if string is empty, however I have an issue where the string does't always exists. I want to avoid appending anything if string does not exists.

public static class StringBuilderExtension
{
    public static void AppendIfNotNull<TValue>(this StringBuilder sb, TValue value, string prefix)
        where TValue : class 
    {
        if (value != null)
        {
            sb.Append(prefix + value);
        }
    }
}

The issue is I am always passing the string key

sb.AppendIfNotNull(" width=\"", component.style.width + "\"");

This will appear as width="" as I physically appended the string. How can I stop this from happening.

I can stop it from appear if I wrap it around an if statement

if (item.width!= null)
{
    sb.AppendIfNotNull(" width=\"", item.width + "\"");
}

Object example. Property might exists in one object but might not on the next. e.g. Do not append color if it does not exists:

{
    'id': 'Test',
    'type': 'Text',
    'style': {
        'color': 'black'
        'textSize': '12'
    }
},
        {
    'id': 'Test',
    'type': 'Text',
    'style': {
        'textSize': '12'
    }
}

Solution

  • You could simply change your add from a string prefix to a function that takes in TValue and returns you a string

    public static class StringBuilderExtension
    {
        public static void AppendIfNotNull<TValue>(this StringBuilder sb, TValue value, Func<TValue, string> transform)
            where TValue : class 
        {
            if (value != null)
            {
                sb.Append( transform( value ));
            }
        }
    }
    

    In this case, your transform will only be called when you are actually having a valid value

    A sample way of using it could be

    sb.AppendIfNotNull( token.style?.width, value => $" width=\"{value}\"" );
    

    Where the ? implies a conditional null check (so if token.style is null, it would also be null)

    I added a small sample to a dotnetfiddle where I did remove the generic type restriction ( because I was throwing numbers in ;) )