How to do ToString for a possibly null object?

C#.NetStringObjectNull

C# Problem Overview


Is there a simple way of doing the following:

String s = myObj == null ? "" : myObj.ToString();

I know I can do the following, but I really consider it as a hack:

String s = "" + myObj;

It would be great if Convert.ToString() had a proper overload for this.

C# Solutions


Solution 1 - C#

C# 6.0 Edit:

With C# 6.0 we can now have a succinct, cast-free version of the orignal method:

string s = myObj?.ToString() ?? "";

Or even using interpolation:

string s = $"{myObj}";

Original Answer:

string s = (myObj ?? String.Empty).ToString();

or

string s = (myObjc ?? "").ToString()

to be even more concise.

Unfortunately, as has been pointed out you'll often need a cast on either side to make this work with non String or Object types:

string s = (myObjc ?? (Object)"").ToString()
string s = ((Object)myObjc ?? "").ToString()

Therefore, while it maybe appears elegant, the cast is almost always necessary and is not that succinct in practice.

As suggested elsewhere, I recommend maybe using an extension method to make this cleaner:

public static string ToStringNullSafe(this object value)
{
    return (value ?? string.Empty).ToString();
}

Solution 2 - C#

string.Format("{0}", myObj);

string.Format will format null as an empty string and call ToString() on non-null objects. As I understand it, this is what you were looking for.

Solution 3 - C#

> It would be great if Convert.ToString() had a proper overload for this.

There's been a Convert.ToString(Object value) since .Net 2.0 (approx. 5 years before this Q was asked), which appears to do exactly what you want:

http://msdn.microsoft.com/en-us/library/astxcyeh(v=vs.80).aspx

Am I missing/misinterpreting something really obvious here?

Solution 4 - C#

With an extension method, you can accomplish this:

public static class Extension
{
    public static string ToStringOrEmpty(this Object value)
    {
        return value == null ? "" : value.ToString();
    }
}

The following would write nothing to the screen and would not thrown an exception:

        string value = null;

        Console.WriteLine(value.ToStringOrEmpty());

Solution 5 - C#

I disagree with that this:

String s = myObj == null ? "" : myObj.ToString();

is a hack in any way. I think it's a good example of clear code. It's absolutely obvious what you want to achieve and that you're expecting null.

UPDATE:

I see now that you were not saying that this was a hack. But it's implied in the question that you think this way is not the way to go. In my mind it's definitely the clearest solution.

Solution 6 - C#

string s = String.Concat(myObj);

would be the shortest way I guess and also have neglible performance overhead. Keep in mind though it wouldn't be quite clear for the reader of the code what the intention is.

Solution 7 - C#

actually I didnt understand what do you want to do. As I understand, you can write this code another way like this. Are you asking this or not? Can you explain more?

string s = string.Empty;
    if(!string.IsNullOrEmpty(myObj))
    {
    s = myObj.ToString();
    }

Solution 8 - C#

I might get beat up for my answer but here goes anyway:

I would simply write

string s = ""
if (myObj != null) {
   x = myObj.toString();
}

Is there a payoff in terms of performance for using the ternary operator? I don't know off the top of my head.

And clearly, as someone above mentioned, you can put this behavior into a method such as safeString(myObj) that allows for reuse.

Solution 9 - C#

I had the same problem and solved it by simply casting the object to string. This works for null objects too because strings can be nulls. Unless you absolutely don't want to have a null string, this should work just fine:

string myStr = (string)myObj; // string in a object disguise or a null

Solution 10 - C#

Some (speed) performance tests summarizing the various options, not that it really matters #microoptimization (using a linqpad extension)

Options

void Main()
{
	object objValue = null;
	test(objValue);
	string strValue = null;
	test(strValue);
}

// Define other methods and classes here
void test(string value) {
	new Perf<string> {
		{ "coallesce", n => (value ?? string.Empty).ToString() },
		{ "nullcheck", n => value == null ? string.Empty : value.ToString() },
		{ "str.Format", n => string.Format("{0}", value) },
		{ "str.Concat", n => string.Concat(value) },
		{ "string +", n => "" + value },
		{ "Convert", n => Convert.ToString(value) },
	}.Vs();
}

void test(object value) {
	new Perf<string> {
		{ "coallesce", n => (value ?? string.Empty).ToString() },
		{ "nullcheck", n => value == null ? string.Empty : value.ToString() },
		{ "str.Format", n => string.Format("{0}", value) },
		{ "str.Concat", n => string.Concat(value) },
		{ "string +", n => "" + value },
		{ "Convert", n => Convert.ToString(value) },
	}.Vs();
}

Probably important to point out that Convert.ToString(...) will retain a null string.

Results

Object
  • nullcheck 1.00x 1221 ticks elapsed (0.1221 ms) [in 10K reps, 1.221E-05 ms per]
  • coallesce 1.14x 1387 ticks elapsed (0.1387 ms) [in 10K reps, 1.387E-05 ms per]
  • string + 1.16x 1415 ticks elapsed (0.1415 ms) [in 10K reps, 1.415E-05 ms per]
  • str.Concat 1.16x 1420 ticks elapsed (0.142 ms) [in 10K reps, 1.42E-05 ms per]
  • Convert 1.58x 1931 ticks elapsed (0.1931 ms) [in 10K reps, 1.931E-05 ms per]
  • str.Format 5.45x 6655 ticks elapsed (0.6655 ms) [in 10K reps, 6.655E-05 ms per]
String
  • nullcheck 1.00x 1190 ticks elapsed (0.119 ms) [in 10K reps, 1.19E-05 ms per]
  • Convert 1.01x 1200 ticks elapsed (0.12 ms) [in 10K reps, 1.2E-05 ms per]
  • string + 1.04x 1239 ticks elapsed (0.1239 ms) [in 10K reps, 1.239E-05 ms per]
  • coallesce 1.20x 1423 ticks elapsed (0.1423 ms) [in 10K reps, 1.423E-05 ms per]
  • str.Concat 4.57x 5444 ticks elapsed (0.5444 ms) [in 10K reps, 5.444E-05 ms per]
  • str.Format 5.67x 6750 ticks elapsed (0.675 ms) [in 10K reps, 6.75E-05 ms per]

Solution 11 - C#

Holstebroe's comment would be your best answer:

string s = string.Format("{0}", myObj);

If myObj is null, Format places an Empty String value there.

It also satisfies your one line requirement and is easy to read.

Solution 12 - C#

Even though this is an old question and the OP asked for C# I would like to share a VB.Net solution for those, who work with VB.Net rather than C#:

Dim myObj As Object = Nothing
Dim s As String = If(myObj, "").ToString()

myObj = 42
s = If(myObj, "").ToString()

Unfortunatly VB.Net doesn't allow the ?-operator after a variable so myObj?.ToString isn't valid (at least not in .Net 4.5, which I used for testing the solution). Instead I use the If to return an empty string in case myObj ist Nothing. So the first Tostring-Call return an an empty string, while the second (where myObj is not Nothing) returns "42".

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncodymanixView Question on Stackoverflow
Solution 1 - C#Andrew HanlonView Answer on Stackoverflow
Solution 2 - C#HolstebroeView Answer on Stackoverflow
Solution 3 - C#Rob GilliamView Answer on Stackoverflow
Solution 4 - C#Pieter van GinkelView Answer on Stackoverflow
Solution 5 - C#steinarView Answer on Stackoverflow
Solution 6 - C#herzmeisterView Answer on Stackoverflow
Solution 7 - C#Serkan HekimogluView Answer on Stackoverflow
Solution 8 - C#jaydelView Answer on Stackoverflow
Solution 9 - C#jahuView Answer on Stackoverflow
Solution 10 - C#drzausView Answer on Stackoverflow
Solution 11 - C#jp2codeView Answer on Stackoverflow
Solution 12 - C#SaschaView Answer on Stackoverflow