This code throws a NullReferenceException if mode is not specified in the pages query string:
bool isAdvancedMode = Request.QueryString["mode"].Equals("advanced");
This is how I work around this:
bool isAdvancedMode = (Request.QueryString["mode"] + "").Equals("advanced");
Is this standard practise, or a hack?
You can use the null-coalescing operator:
bool isAdvancedMode = (Request.QueryString["mode"] ?? String.Empty).Equals("advanced");
Edit: If you want to re-use this logic, try this extension method:
public static bool EqualIfExists(this string source, string comparison)
{
return source != null && source.Equals(comparison);
}
Request.QueryString["mode"].EqualIfExists("advanced")
Add more overrides to match Equals signature. I'm not sure if this is a good name (I think it is not).
Well, I would recommend this instead:
bool isAdvancedMode = (Request.QueryString["mode"] ?? "").Equals("advanced");
In fact, this is what your code compiles to (Nearer the bottom, but it's a good read so I'd read it all). Yours is good practice, but this is a bit more clear.
Why not use the null coalescing operator?
bool isAdvancedMode = (Request.QueryString["mode"] ?? String.Empty).Equals("advanced");
Different approach, while a bit more code, I think is more clear the intent.
bool isAdvancedMode = String.IsNullOrWhitespace(Request.QueryString["mode"]) ?
false : Request.QueryString["mode"].Equals("advanced")
what about this
bool isAdvancedMode=(Request.QueryString["mode"] ?? string.Empty).Equals("advanced");
Related
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()
}
Is there a shorthand when checking a boolean for true?
Example:
if (autoConnect) Connect();
We can do
return IsOpen() ? true : false;
But I cant get
autoConnect ? Connect();
running. Is there a way to do this?
You could write an extension method:
public static void _(this bool b, Action ifTrue)
{
if (b) { ifTrue(); }
}
then you could write:
autoConnect._(Connect);
although obviously this is not very readable and is not recommended.
The only thing you can shorten is to remove the conditional operator:
return IsOpen() ? true : false;
and just
return IsOpen();
No, no way to get autoConnect ? Connect(); working.
just return the bool value, don't need a ternary operator:
return IsOpen();
Alternativelly, you return some values when a value you want to test can be null using the ?? operator, for sample:
return a ?? b;
If a is null, then return b.
To answer your question, no, there is no shorthand to make
if (autoConnect) Connect();
any shorter. Also, your proposed solution only saves up 3 characters, which is an unnecessary golfing of otherwise perfectly readable code.
As siride says if (autoConnect) Connect(); is the shortest way. Altough, this is just while writing code. Whenever the compiler compiles the code it will become the same as using if (autoConnect) { Connect(); } or if (autoConnect == true) { Connect(); }.
You should use whatever you find the most clean or easiest reading.
Does C# have a similar operation to JavaScript's || setter?
For example, in JavaScript, if I want to check if a value is null and set a default, I can do something like this:
function foo(val){
this.name = val || "foo";
}
But, when I want this functionality in C# I have to go this route:
public Foo(string val)
{
this.name = (string.IsNullOrEmpty(val) ? "foo" : val);
}
I know this is petty and that beggars can't be choosers but, if at all possible, I'd like to avoid getting any answers that involve crazy hacks or extension methods. I'm fine with using the ternary operator, but I was just curious if there was a language feature I'd missed.
Update:
Great answers all around, but J0HN and Anton hit it on the head. C# doesn't do "falsy" values like JavaScript would in the example above, so the ?? operator doesn't account for empty strings.
Thanks for your time and the great responses!
There's a null-coalescing operator in C#, though it can't handle all the quirkiness of JavaScript:
this.name = val ?? "foo";
Since an empty string is false in JavaScript, this C# code will behave differently from its JS counterpart.
There is a ?? operator that essentially is the same as COALESCE operator in SQL:
int? a = null; //int? - nullable int
int q = a??1; // q is set to one;
However, ?? does not check the string for emptiness, so it does not share the same meaning as javascript's ||, which treats empty strings as false as well.
You can use ??:
private int Foo(string val){
this.name = val ?? "foo";
}
Go with this
this.name = val ?? "foo";
Yep, use ??:
private int Foo(string val){
this.name = val ?? "foo";
}
Check Msdn for more information: ?? Operator
It seems that there's some type confusion in the ternary operator. I know that this has been addressed in other SO threads, but it's always been with nullables. Also, for my case I'm really just looking for a better way.
I'd like to be able to use
proc.Parameters[PARAM_ID].Value =
string.IsNullOrEmpty(dest.Id) ? DBNull.Value : dest.Id;
but instead I'm stuck with this:
if (string.IsNullOrEmpty(dest.Id))
{
proc.Parameters[PARAM_ID].Value = DBNull.Value;
}
else
{
proc.Parameters[PARAM_ID].Value = dest.Id;
}
The ternary operator fails because there's no conversion possible between DBNull and string, and as silly as that seems considering Value is object, the compiler kicks it back to me and I'm forced to care. The answer to the nullable version of this question is to just cast null to string and be done with it; DBNull can't be cast to string, though, so no luck there.
Is there a more concise way to do this (without using nullables, by the way?)
Thanks!
You could change your first statement to:
proc.Parameters[PARAM_ID].Value =
string.IsNullOrEmpty(dest.Id) ? (object)DBNull.Value : dest.Id;
The Value property is of type object, so you should cast to object, not string:
proc.Parameters[PARAM_ID].Value = string.IsNullOrEmpty(dest.Id)
? (object)DBNull.Value
: (object)dest.Id;
Or you could add an extension method such as:
public static class DBNullExtensions
{
public static object AsDBNullIfEmpty(this string value)
{
if (String.IsNullOrEmpty(value))
{
return DBNull.Value;
}
return value;
}
}
And then you could just say
proc.Parameters[PARAM_ID].Value = dest.Id.AsDBNullIfEmpty();
(Adapted from Phil Haack)
Readable and concise, no?
What about using the ?? null-coalescing operator More details about ?? operator
proc.Parameters[PARAM_ID].Value = dest.Id ?? (object)DBNull.Value;
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);