jhunter
jhunter

Reputation: 1882

Negate the null-coalescing operator

I have a bunch of strings I need to use .Trim() on, but they can be null. It would be much more concise if I could do something like:

string endString = startString !?? startString.Trim();

Basically return the part on the right if the part on the left is NOT null, otherwise just return the null value. I just ended up using the ternary operator, but is there anyway to use the null-coalescing operator for this purpose?

Upvotes: 20

Views: 3535

Answers (8)

AxelEckenberger
AxelEckenberger

Reputation: 16926

Use

string endString = (startString ?? "").Trim();

This uses an empy string if startString is null. This, however, does not return null when endString is null.

Fast-forward to 2021:
10 years later startString?.Trim() is definitely the better option. And this does return null.

Upvotes: 0

Steven Rumbalski
Steven Rumbalski

Reputation: 45542

Starting with C# 6.0 (.NET Framework 4.6 / Visual Studio 2015) you can use null-conditional member access:

 string? endString = startString?.Trim();

Upvotes: 4

Dai
Dai

Reputation: 155145

Sorry for the necromancy, but I was having this same problem and I solved this using a lambda operation. It isn't the prettiest, but it keeps my code succinct.

It's a shame C# doesn't support static imports or individual function imports, but anyway:

Define this function somewhere:

private static TResult N<TParent,TResult>(TParent parent, Func<TParent,TResult> operation) {
    if( parent == null ) return default(TResult);
    return operation( parent );
}

Then to use it in your example:

String endString = N(startString, s => s.Trim());

The N function returns null if the first argument is null, otherwise it will evaluate the specified lambda function with the value as the argument.

You can nest it, of course, like so. For example, to safely dereference a long chain, e.g.

String someValue = someObject.SomeProperty.SomeOtherProperty.SomeMethod().SomeFinalProperty;

if any of those properties or methods returns null then you have to insert null checks everywhere, or you could do this:

String someValue = N(N(N(N(someObject, o => o.SomeProperty), o => o.SomeOtherProperty), o => o.SomeMethod()), o => o.SomeFinalProperty);

As I said, it isn't the prettiest :)

You could simplify this by making N an extension method of System.Object, like so:

String someValue = someObject.N( o => o.SomeProperty ).N( o => o.SomeOtherProperty ).N( o => o.SomeMethod() ).N( o => o.SomeFinalProperty );

...which I think is a lot tidier.

Upvotes: 1

Daniel DiPaolo
Daniel DiPaolo

Reputation: 56390

string endString = string.IsNullOrEmpty(startString) ? startString : startString.Trim();

Though I've also gone the route of writing a string extension method called "safeTrim" which does what you're describing in one method instead of having to use this recipe every time. Check out Kevin's respone for the code.

EDIT: wow I had it all kinds of backwards, wrongly named variables and reversed ternary operators, all the more reason to write one extension method and code check it better than I did!

Upvotes: 4

user7116
user7116

Reputation: 64068

Not to spec: Not that I like it, but you could use:

string endString = (startString ?? String.Empty).Trim();

To spec, better as an Extension method like @Kevin's:

string endString = (startString == null ? null : startString.Trim());

Upvotes: 12

Igal Tabachnik
Igal Tabachnik

Reputation: 31548

As as side note, if you're using .NET 4, there's a new convenient method String.IsNullOrWhiteSpace which you can use.

Upvotes: -1

Heinzi
Heinzi

Reputation: 172260

The following doesn't propagate null but it accepts null as a parameter and returns an empty string in that case.

using Microsoft.VisualBasic;  // you need to add a reference to Microsoft.VisualBasic.dll

    ...
    string endString = Strings.Trim(startString);
    ...

duck&run...

Upvotes: -1

kemiller2002
kemiller2002

Reputation: 115488

You could create an extension method which returns null when it tries to trim the value.

public String TrimIfNotNull(this string item)
{
   if(String.IsNullOrEmpty(item))
     return item;
   else
    return item.Trim();
}

Note you can't name it Trim because extension methods can't override instance methods.

Upvotes: 13

Related Questions