1

In his answer to this question, BlackBear suggested replacing

 string y = Session["key"] == null ? "none" : Session["key"].ToString();

with

 string y = (Session["key"] ?? "none").ToString();

This works great if Session["key"] is a string value, but what if I want to do this with an object? For example, I could do this:

 string y = GetMyObject() == null ? "none" : GetMyObject().ToString();

But what if I don't want to evaluate GetMyObject() twice? Is my only choice to store the results in a variable, then check that variable for null?

 var x = GetMyObject();
 string y = (x == null) ? "none" : x.ToString();

Edit: This is all theoretical - I've run into it before, but I don't have a specific example in front of me right now. That being said, here's an example class.

class MyObject
{
   private MyObject() { }
   public MyObject GetMyObject() { return new MyObject(); }
   public override string ToString() { return "A String"; }
}

If I do string y = (GetMyObject() ?? "none").ToString();, I get

Operator '??' cannot be applied to operands of type 'MyObject' and 'string'".

Ideally, I'd be able to do

 string y = GetMyObject().ToString() ?? "none";

and have it work even if GetMyObject() is null. Basically null-coalescing operator acting as a self-contained try {} catch (NullReferenceException) {}. I know I can't, but that would be the ideal.

Community
  • 1
  • 1
Bobson
  • 13,498
  • 5
  • 55
  • 80
  • 2
    You've answered your question yourself – sll Mar 23 '12 at 19:35
  • Without seeing GetMyObject(), sounds like you are on the right track. You have to bring MyObject into memory at some point, no sense in doing it twice. – Jeff Willener Mar 23 '12 at 19:36
  • 4
    Hmm... with what type of object does `string y = (Session["key"] ?? "none").ToString()` *not* work? – Edward Thomson Mar 23 '12 at 19:37
  • As an aside, especially if you are in control of the code, you might be interested in the [null object pattern](http://en.wikipedia.org/wiki/Null_Object_pattern). – Jim D'Angelo Mar 23 '12 at 19:44
  • possible duplicate of [What is the proper way to check for null values?](http://stackoverflow.com/questions/9788466/what-is-the-proper-way-to-check-for-null-values) – Edward Thomson Mar 23 '12 at 19:46
  • @sll - I know there's plenty of other ways to do it, one of which I provided. I'm looking specifically for a way to do it without creating a new variable and without calling the function twice. The Null coalescer *could* do it, in theory, but doesn't. – Bobson Mar 23 '12 at 20:12
  • @EdwardThomson - See my edit. I don't know if sticking a MyObject in Session will cause a runtime exception when trying to coalesce it to a string or not, but I'm not using Session. – Bobson Mar 23 '12 at 20:14

3 Answers3

4

BlackBear's solution works perfectly fine as it is:

string y = (GetMyObject() ?? "none").ToString();

That will either set y to GetMyObject().ToString() (if GetMyObject() returns a non-null reference) or to "none".ToString() otherwise. There's a tiny, tiny hit calling ToString() on a string, but I'd very much doubt that it's significant.

That's fine if GetMyObject() returns object. If it returns some specific type which string can't be converted to, just cast one of them to object, e.g.

string y = (GetMyButton() ?? (object) "none").ToString();

Having said that, I'd probably use an extension method at that point - or just do it longhand.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Casting it to object works. I'd almost always prefer the longer form, but it's good to know that it *is* possible to do it on the one line. Thanks! – Bobson Mar 23 '12 at 21:05
2

It looks like you would like to use the null-safe dereferencing operator, written as ?. in some languages:

var x = GetMyObject()?.ToString() ?? "none";

Unfortunately C# doesn't have this operator. You can do it the way you are already doing it.

This operator was considered for addition to the language. However it didn't make it into any released version of C#.

Community
  • 1
  • 1
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • 2
    Never heard about such one, could you please bring some example from other languages? – sll Mar 23 '12 at 19:35
  • Yeah, that's the kind of operator I'm looking for. Good to know that it doesn't exist. It'd certainly have my vote for inclusion, if I had a vote. – Bobson Mar 23 '12 at 21:03
0

What's missing in code can [usually] be added:

private static object SafeToString( object obj, string defaultString = "none" )
{
    return obj != null ? obj.ToString() : defaultString;
}
AVIDeveloper
  • 2,954
  • 1
  • 25
  • 32
  • Caution with this approach of an Object Extension hiding nulls. If used excessively you can actually hide bugs and lead to more/bad code. I love extensions, just keep this in mind when using one like this. – Jeff Willener Mar 23 '12 at 19:48