2

I have a simple class which has a ToString implemented which I am happy with the content. I am trying to decide what is the (most) correct way by seeing if there are any pro's/con's for the various options.

For the example below:

  • Class: Astronaut
  • Variable of type Astronaut: person

Options that I am just snow balling here:

  1. string result = person == null ? "Unknown Astronaut" : person.ToString();
  2. string result = person.ToString() ?? "Unknown Astronaut";
  3. string result = (person ?? "Unknown Astronaut").ToString();
  4. string result = person ?? (object)"Unknown Astronaut";

My views on those are

  1. Very verbose & I don't need that level of verbosity.
  2. Much better than 1 but the ToString feels ugly plus worried of exceptions in that ToString code.
  3. This seems popular (here & here) but I am not sure it will work. Won't the compiler complain about a string & a Astronaut type not being the same type and thus can not be used in a coalese.
  4. This is the one I am happiest with now, but it means a box & ToString should person be null.

In summary:

  • Any pro's/con's to any of the above?
  • Any options you can think of?
Community
  • 1
  • 1
Robert MacLean
  • 38,975
  • 25
  • 98
  • 152
  • I've never even seen option 2 with reference types... wow o___o – user541686 Apr 18 '11 at 07:57
  • 1
    Option 2 will throw an exception if person is null - so it's not really an option in this context. – Anders Fjeldstad Apr 18 '11 at 07:59
  • Why would 4 result in a boxing operation when there are no value types involved? – Brian Rasmussen Apr 18 '11 at 07:59
  • 1
    4 will only work if person can be implicitly converted to string, i.e. has an implict string cast overload – Jodrell Apr 18 '11 at 08:08
  • +1 to Jodrell, and even there is a implicit convert, it doesn't compile, because of the unnecessary (object) convert in front of "Unknown Astronaut". There is no explicitly convert from object to string. – Cheng Chen Apr 18 '11 at 08:10
  • 1 and 3 are the only options that actually work in all cases – Jodrell Apr 18 '11 at 08:17
  • @Brian - my thinking is that it will box string to an object, then it will call ToString on the object when it needs to set the value. – Robert MacLean Apr 18 '11 at 08:18
  • @Jodrell: you missed the (object), so it works as any class can implicitly be converted to object. it is not a string at that point. – Robert MacLean Apr 18 '11 at 08:19
  • @Danny: It does compile and it does work. Not sure why you think you can't explicitly convert from string to object. – Robert MacLean Apr 18 '11 at 08:19
  • @Jodrell: Why does 4 not work in all cases? What case would it fail in? – Robert MacLean Apr 18 '11 at 08:20
  • 1
    @Robert: Using option 4, when person is not null, it equals to `string result = person;`, which requires the instance person can be converted to a string implicitly. When person is null, it equals to `string result = (object)"blabla";`, you are assigning an object to a string, which is not allowed, because an object can't be implicitly/explicitly converted to a string. – Cheng Chen Apr 18 '11 at 08:23
  • @Danny - I see what you saying – Robert MacLean Apr 18 '11 at 10:05
  • I reckon Danny cleared up the confusion, I would go for 3. – Jodrell Apr 18 '11 at 13:09

4 Answers4

6

I prefer an extension method:

public static string SafeToString(this Object obj)
{
   return obj.SafeToString(string.Empty);
}

public static string SafeToString(this Object obj, string defaultString)
{
   return obj == null ? defaultString : obj.ToString();
}

So to your question:

string result = person.SafeToString("Unknown Astronaut");
Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • I agree with an method (it's my class, I can add a normal one too) but what do you do internally? You have choosen option 1, which I stated in the question that is very verbose. Are you saying option 1 is best? – Robert MacLean Apr 18 '11 at 08:21
  • @robert Maclean: Yes. But you can't put the code like option 1 everywhere. You need to put the logic in one method, and next time you needn't to repeat. – Cheng Chen Apr 18 '11 at 08:25
  • @Danny - No issue there, but it comes down to what do you put in the method then which you haven't answered. You just say 1 or 3, which is better or are they exactly the same? – Robert MacLean Apr 18 '11 at 10:06
  • @Robert: They are the same at the result. – Cheng Chen Apr 18 '11 at 10:45
  • @Danny - Realise that the result is the same, thus my question wondering if there is any other pro's & con's around them? Performance, stability etc... or are you saying they are exactly the same? – Robert MacLean Apr 18 '11 at 12:31
3

Create a static ToString method and just call it like:

string result = Astronaut.ToString(person);

Best way to factor out common code.

user541686
  • 205,094
  • 128
  • 528
  • 886
1

I remember a design patterns book telling me about some object that you instantiate for the sole purpose of filling in null objects. They would return things like the empty string for name, or 0 for length, and so on. Doesn't sound like a bad idea.

You could also implement it as a static method of the Astronaut class:

String result = Astronaut.getName(person);
0

You could also place a static method in the class that converts an Astronaut to string or returns "Unknown astronaut" if the argument was null.

In a similar vein, you could make it an extension method and call it directly on a variable of that type, even if it's null.

Joey
  • 344,408
  • 85
  • 689
  • 683