Negate the null-coalescing operator - c#

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?

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.

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

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!

Starting with C# 6.0 (.NET Framework 4.6 / Visual Studio 2015) you can use null-conditional member access:
string? endString = startString?.Trim();

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.

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.

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

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

Related

C# Null propagating operator / Conditional access expression & if blocks

The Null propagating operator / Conditional access expression coming in c#-6.0 looks like quite a handy feature. But I'm curious if it will help solve the problem of checking if a child member is not null and then calling a Boolean method on said child member inside an if block:
public class Container<int>{
IEnumerable<int> Objects {get;set;}
}
public Container BuildContainer()
{
var c = new Container();
if (/* Some Random Condition */)
c.Objects = new List<int>{1,2,4};
}
public void Test()
{
var c = BuildContainer();
//Old way
if ( null != c && null != c.Objects && c.Objects.Any())
Console.Write("Container has items!");
//C# 6 way?
if (c?.Object?.Any())
Console.Write("Container has items!");
}
Will c?.Object?.Any() compile? If the propagating operator short circuits (I assume that's the right term) to null then you have if (null), which isn't valid.
Will the C# team address this concern or am I missing the intended use case for the null propagating operator?
It won't work this way. You can just skip the explanation and see the code below :)
As you know ?. operator will return null if a child member is null. But what happens if we try to get a non-nullable member, like the Any() method, that returns bool? The answer is that the compiler will "wrap" a return value in Nullable<>. For example, Object?.Any() will give us bool? (which is Nullable<bool>), not bool.
The only thing that doesn't let us use this expression in the if statement is that it can't be implicitly casted to bool. But you can do comparison explicitly, I prefer comparing to true like this:
if (c?.Object?.Any() == true)
Console.Write("Container has items!");
Thanks to #DaveSexton there's another way:
if (c?.Object?.Any() ?? false)
Console.Write("Container has items!");
But as for me, comparison to true seems more natural :)
Null-conditional operator would return null or the value at the end of expression. For value types It will return result in Nullable<T>, so in your case it would be Nullabe<bool>. If we look at the example in the document for Upcoming Features in C# (specified here), it has an example:
int? first = customers?[0].Orders.Count();
In the above example, instead of int, Nullable<int> would be returned. For bool it will return Nullable<bool>.
If you try the following code in Visual Studio "14" CTP:
Nullable<bool> ifExist = c?.Objects?.Any();
The result of the above line would be a Nullable<bool>/bool?. Later you can do the comparison like:
Using null-coalescing operator ??
if (c?.Object?.Any() ?? false)
Using Nullable<T>.GetValueOrDefault Method
if ((c?.Objects?.Any()).GetValueOrDefault())
Using comparison against true
if (c?.Objects?.Any() == true)
var x = c?.Objects?.Any() is going to give you a nullable boolean, and as others have said, this means you can use an equality operator like this
x == true
or you can use null coalescing like this to have your result not be nullable
var x = c?.Objects?.Any() ?? false
But, personally, I think that 3-state (nullable) booleans are code smell. Even if this one is practically invisible, its existence should encourage you to think about what you are actually trying to do and determine if a nullable boolean is actually the way to go. In this case, I think that what you really want to do is something like this -
var objects = c?.Objects ?? Enumerable.Empty<Object>();
if (objects.Any())
{
...
}
Put that in an extension method and it will be even more succinct -
public static bool IsNullOrEmpty<T>(this IEnumerable<T> collection)
{
return !(collection ?? Enumerable.Empty<T>()).Any()
}

How to check if String is null

I am wondering if there is a special method/trick to check if a String object is null. I know about the String.IsNullOrEmpty method but I want to differentiate a null String from an empty String (="").
Should I simply use:
if (s == null) {
// blah blah...
}
...or is there another way?
An object can't be null - the value of an expression can be null. It's worth making the difference clear in your mind. The value of s isn't an object - it's a reference, which is either null or refers to an object.
And yes, you should just use
if (s == null)
Note that this will still use the overloaded == operator defined in string, but that will do the right thing.
You can use the null coalescing double question marks to test for nulls in a string or other nullable value type:
textBox1.Text = s ?? "Is null";
The operator '??' asks if the value of 's' is null and if not it returns 's'; if it is null it returns the value on the right of the operator.
More info here:
https://msdn.microsoft.com/en-us/library/ms173224.aspx
And also worth noting there's a null-conditional operator ?. and ?[ introduced in C# 6.0 (and VB) in VS2015
textBox1.Text = customer?.orders?[0].description ?? "n/a";
This returns "n/a" if description is null, or if the order is null, or if the customer is null, else it returns the value of description.
More info here:
https://msdn.microsoft.com/en-us/library/dn986595.aspx
To be sure, you should use a function to check for null and empty as below:
string str = ...
if (!String.IsNullOrEmpty(str))
{
...
}
If you are using C# 7.0 or above you can use is null:
if (s is null) {
// blah blah...
}
Also, note that when working with strings you might consider also using IsNullOrWhiteSpace that will also validate that the string doesn't contain only spaces.
For .net 5 (probably also for .net Core 3.1)
Different possibility to write but always the same problem.
string wep = test ?? "replace";
Console.WriteLine(wep);
result: "replace"
or
string test=null;
test ??= "replace";
Console.WriteLine(test);
test="";
test??="replace";
Console.WriteLine(test);
first try: "replace"
second try: blank
string test="";
if(test is null)
Console.WriteLine("yaouh");
else
Console.WriteLine("Not yahouu");
Result: "Not yahou"
You can check with null or Number.
First, add a reference to Microsoft.VisualBasic in your application.
Then, use the following code:
bool b = Microsoft.VisualBasic.Information.IsNumeric("null");
bool c = Microsoft.VisualBasic.Information.IsNumeric("abc");
In the above, b and c should both be false.

Inline conditional c# - next best solution?

It seems the compiler is not going let this syntax fly.
void main()
{
foo(false?0:"");
}
void foo(int i) {return;}
void foo(string s) {return;}
The only other way I can see of fixing this is something as follows:
void bar(object o)
{
if (o is string){//do this}
else{//im an int, do this}
}
Anyone have any better ideas?
You cannot use a method with a void return type in a ternary expression in this way. End of story.
To understand why this is, remember what the ternary operator actually does -- it evaluates to the following:
(condition ? [true value] : [false value])
What this implies is that the following code:
int x = a ? b : c;
Must be rewritable to:
int x;
if (a)
{
x = b;
}
else
{
x = c;
}
The two above are logically identical.
So how would this work with a method with void as its return type?
// Does this make sense?
int x = condition ? foo(s) : foo(i);
// Or this?
if (condition)
{
x = foo(s);
}
else
{
x = foo(i);
}
Clearly, the above is not legal.
That said, others' suggestions would otherwise be valid if only your foo overloads returned a value.
In other words, if your signatures looked like this:
object foo(string s);
object foo(int i);
Then you could do this (you're throwing away the return value, but at least it'll compile):
object o = condition ? foo(0) : foo("");
Anyway, the ol' if/else is your best bet, in this case.
The method call of foo is determined at compile time, so it cannot call a different method (or overload) based on the result of evaluating the condition. Instead, try something like this:
condition ? foo(0) : foo("")
This way, the compiler will succeed in performing overload resolution and will resolve the first call to foo(int) and the second call to foo(string).
EDIT: As noted by other, you cannot use the ?: operator as a statement, nor can you use methods which return void in it. If your actual methods return compatible types, you could do something like:
int result = condition ? foo(0) : foo("");
If not, you must use an if:
if (condition)
foo(0);
else
foo("");
You're example doesn't make a whole lot of sense (the second example doesn't relate to the first).
I think the first example would be fine as:
void main()
{
foo("");
}
Since 0 will never be passed anyway (false is always false) and you can't use the inline conditional operator without an assignment somewhere (which your example is lacking).
As for the second way, that is probably how I would prefer to see it:
void bar(object o)
{
if(o is string) foo(o as string);
else foo((int)o);
}
I wouldn't pass in an object as a parameter. The int will be boxed, which is a little less efficient. Let the compiler figure out which method to call.
If you wrote:
foo(0);
foo("");
The appropriate method would be called. You could also write:
if (condition) {
foo(0);
} else {
foo("");
}
Depending on what you're trying to do (your example is lacking in a little detail).
If you use Inline if expressions in C#, both parts before and after the ":" have to be of the same type. What you are intending would never work.
Even if you like to do something like this:
DateTime? theTime = true ? DateTime.Now : null;
The compiler is not satisfied. In this case you will have to use:
DateTime? theTime = true ? DateTime.Now : default(DateTime?);
The conditional operator needs the true and false part to be of the same type. Which is why it's not compiling.
var x = condition ? 0 : "";
What type should the compiler choose for x? If you really want it to choose object make a cast or you could force it to choose dynamic in which case method overload would still work but you loose type safety. Both are however strong smells.
Having to test the runtime type is usually a design error but with the limited code (that will always have the same result) it's hard to help with a different approach that would require testing on runtime types
This:
foo(false?0:"")
Could be this:
false ? foo(0) : foo("")
Both results of the conditional operator must of the same type (or be implicitly convertible). So foo(false ? 0 : "") won't work because it is trying to return an Int32 and a String. Here's more information on the conditional operator.
The fix I would do is change that line to false ? foo(0) : foo("").
EDIT: Derp, can't use a conditional operator just in the open like that. They can only be used for assignments. You'll have to use a if/else block. Not in one line, but it'll do in a pinch.

Null and blank values

What's the best way of writing robust code so that a variable can be checked for null and blank.
e.g.
string a;
if((a != null) && (a.Length() > 0))
{
//do some thing with a
}
For strings, there is
if (String.IsNullOrEmpty(a))
You can define an extension method to allow you to do this on many things:
static public bool IsNullOrEmpty<T>(this IEnumerable <T>input)
{
return input == null || input.Count() == 0;
}
It already exists as a static method on the System.String class for strings, as has been pointed out.
And if you are using .NET 4.0 you might want to take a look at String.IsNullOrWhiteSpace.
From version 2.0 you can use IsNullOrEmpty.
string a;
...
if (string.IsNullOrEmpty(a)) ...
if(string.IsNullOrEmpty(string name))
{
/// write ur code
}
for strings:
string a;
if(!String.IsNullOrEmpty(a))
{
//do something with a
}
for specific types you could create an extention method
note that i've used HasValue instead of IsNullorEmpty because 99% of the times you will have to use the !-operator if you use IsNullOrEmpty which I find quite unreadable
public static bool HasValue(this MyType value)
{
//do some testing to see if your specific type is considered filled
}
I find Apache Commons.Lang StringUtils (Java)'s naming a lot easier: isEmpty() checks for null or empty string, isBlank() checks for null, empty string, or whitespace-only. isNullOrEmpty might be more descriptive, but empty and null is, in most cases you use it, the same thing.

Shortest way to check for null and assign another value if not

I am pulling varchar values out of a DB and want to set the string I am assigning them to as "" if they are null. I'm currently doing it like this:
if (string.IsNullOrEmpty(planRec.approved_by) == true)
this.approved_by = "";
else
this.approved_by = planRec.approved_by.toString();
There seems like there should be a way to do this in a single line something like:
this.approved_by = "" || planRec.approved_by.toString();
However I can't find an optimal way to do this. Is there a better way or is what I have the best way to do it?
Try this:
this.approved_by = IsNullOrEmpty(planRec.approved_by) ? "" : planRec.approved_by.toString();
You can also use the null-coalescing operator as other have said - since no one has given an example that works with your code here is one:
this.approved_by = planRec.approved_by ?? planRec.approved_by.toString();
But this example only works since a possible value for this.approved_by is the same as one of the potential values that you wish to set it to. For all other cases you will need to use the conditional operator as I showed in my first example.
Starting with C# 8.0, you can use the ??= operator to replace the code of the form
if (variable is null)
{
variable = expression;
}
with the following code:
variable ??= expression;
More information is here
You are looking for the C# coalesce operator: ??. This operator takes a left and right argument. If the left hand side of the operator is null or a nullable with no value it will return the right argument. Otherwise it will return the left.
var x = somePossiblyNullValue ?? valueIfNull;
The coalesce operator (??) is what you want, I believe.
My guess is the best you can come up with is
this.approved_by = IsNullOrEmpty(planRec.approved_by) ? string.Empty
: planRec.approved_by.ToString();
Of course since you're hinting at the fact that approved_by is an object (which cannot equal ""), this would be rewritten as
this.approved_by = (planRec.approved_by ?? string.Empty).ToString();
With C#6 there is a slightly shorter way for the case where planRec.approved_by is not a string:
this.approved_by = planRec.approved_by?.ToString() ?? "";
Use the C# coalesce operator: ??
// if Value is not null, newValue = Value else if Value is null newValue is YournullValue
var newValue = Value ?? YourNullReplacement;
To extend #Dave's answer...if planRec.approved_by is already a string
this.approved_by = planRec.approved_by ?? "";
The accepted answer was correct in time, when it was given.
For people still finding this question:
Today you can use the ??= Operator.
e.g:
private string _test = null;
private void InitIfNull(){
_test ??= "Init";
}
To assign a non-empty variable without repeating the actual variable name (and without assigning anything if variable is null!), you can use a little helper method with a Action parameter:
public static void CallIfNonEmpty(string value, Action<string> action)
{
if (!string.IsNullOrEmpty(value))
action(value);
}
And then just use it:
CallIfNonEmpty(this.approved_by, (s) => planRec.approved_by = s);
You can also do it in your query, for instance in sql server, google ISNULL and CASE built-in functions.
I use extention method SelfChk
static class MyExt {
//Self Check
public static void SC(this string you,ref string me)
{
me = me ?? you;
}
}
Then use like
string a = null;
"A".SC(ref a);

Categories

Resources