Pergunta

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.

Foi útil?

Solução

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.

Outras dicas

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#.

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

private static object SafeToString( object obj, string defaultString = "none" )
{
    return obj != null ? obj.ToString() : defaultString;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top