Here is some example code to get started:
class Foo
{
public bool? IsValid { get; set; }
}
// later in some other function...
void DoStuff( Foo myFoo )
{
myControlState.Visible = myFoo.IsValid.HasValue ? myFoo.IsValid.Value : false;
}
I run into a lot of situations where I have to use a ternary operator like above to properly use a nullable bool. It would be nice if there was a slightly simpler way of getting the value of the bool without throwing exceptions. The code above seems straight-forward but there are much more complex situations where this ends up being a lot of code. I was hoping for something simple like:
myControlState.Visible = GetNullableValue<bool>( myFoo );
Does anyone have any cleaner alternatives to the ternary operator?
you can use the null-coalescing operator if that makes it more readable.
myControlState.Visible = myFoo.IsValid ?? false;
This is more elegant
myControlState.Visible = myFoo.IsValid ?? false;
myControlState.Visible = myFoo.IsValid.GetValueOrDefault();
If you are reading bit values from the SQL server and want to check against null errors, Use the following Extension method against the data Row
public static T GetValueOrDefault<T>(this DataRow row, string key)
{
return row.GetValueOrDefault(key, default(T));
}
and when you are reading data from the SQL server put in.
Boolean IsVisible = GetValueOrDefault<string>("FieldName");
Related
Working with all the dictionaries within ASP.NET MVC (like RouteData, DataTokens etc), I often find myself wanting to do stuff like:
bool isLolCat = routeData["isLolcat"] as bool
that would return the casted value, or default (false in this case) when the value is null.
Is there any short, readable, simple way to do this, or am I better off writing a helper extension method?
An extension method would something like this.
bool isLolCat = routeData["isLolcat"].TryCast<bool>();
I rather don't want to reinvent the wheel with custom syntax if there is a common way to do this.
I don't want to litter my code with a few lines, when I just to try to get a bool out of a dictionary.
Maybe you like any of these:
(routeData["isLolcat"] as bool?).GetValueOrDefault()
(routeData["isLolcat"] as bool?).GetValueOrDefault(false)
(routeData["isLolcat"] as bool?) ?? false
If not you'll have to write a helper. I actually recommend using a helper because the code that I posted kind of obfuscates what you mean. I'd rather see this:
routeData.GetOrDefault<bool>("isLolcat")
Because this documents in writing what you intend.
Is there any short, readable, simple way to do this, or am I better off writing a helper extension method?
I'd say you would be better writing your own extension because you can make your intentions clear
public static class Ext
{
public static T CastOrDefault<T>(this object obj)
{
return obj is T ? (T)obj : default(T);
}
}
...
bool isLolCat = RouteData["isLolCat"].CastOrDefault<bool>();
Suggestion - If you wanted to keep it short, you could call it something like As<T>
bool isLolCat = RouteData["isLolCat"].As<bool>();
string str = RouteData["isLolCat"].As<string>(); // null
I don't think there's a most common way, all casting / conversion operations have their own idiosyncrasies.
For example, Convert.ToBool can accept strings to convert, do you want this to convert, or should this fail?
x as bool will give you null if it's not of type bool.
I think it would be best to write an extension method for RouteData.
public static T GetValueOrDefault<T>(this RouteData routeData, string field)
{
var value = routeData[field];
if (value is T)
{
return (T)value;
}
return default(T);
}
This way you're operating on the RouteData class and not potentially null values.
Usage:
var isLolCat = routeData.GetValueOrDefault<bool>("IsLolCat");
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.
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");
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.
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.