Negate the null-coalescing operator

妖精的绣舞 提交于 2019-12-09 14:29:14

问题


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?


回答1:


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.




回答2:


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());



回答3:


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!




回答4:


Use

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

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




回答5:


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.




回答6:


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




回答7:


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




回答8:


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

 string? endString = startString?.Trim();


来源:https://stackoverflow.com/questions/2852875/negate-the-null-coalescing-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!