I have a simple extension method for string class which will strip all non numeric characters from a string. So if I have a string like for example a phone number such as "(555) 215-4444" it will convert it to "5552154444". It looks like this:
public static string ToDigitsOnly(this string input)
{
Regex digitsOnly = new Regex(#"[^\d]");
return digitsOnly.Replace(input, String.Empty);
}
I am just wondering what is the most elegant way to handle a null value here? Is there a typical pattern to follow in these cases, such as return back a null value if a null is passed in? It seems since I'm extending the string class here I may want to allow null values and not throw a arguement exception (since I'm not really passing in an arguement when I use this...) ? But some might argue I should throw an exception like a 'normal' method would. What's the best practice you are using here?
Thanks!
You can follow the principle of least surprise: use pattern implemented in LINQ:
public static string ToDigitsOnly(this string input)
{
if(input == null)
throw new ArgumentNullException("input");
Regex digitsOnly = new Regex(#"[^\d]");
return digitsOnly.Replace(input, String.Empty);
}
You can use method, proposed by Jon Skeet. It will reduce your check simply to
input.ThrowIfNull("input");
Also Jon has a good section 10.2.4 Calling a method on a null reference in C# in Depth, quote:
CHECKING FOR NULLITY As a conscientious developer, I’m sure that your
production methods always check their arguments’ validity before
proceeding. One question that naturally arises from this quirky
feature of extension methods is what exception to throw when the first
argument is null (assuming it’s not meant to be). Should it be
ArgumentNullException, as if it were a normal argument, or should it
be NullReferenceException, which is what would’ve happened if the
extension method had been an instance method to start with? I
recommend the former: it’s still an argument, even if the extension
method syntax doesn’t make that obvious.
I see this recommendation as (and from my personal experience): it's always better to check for null, specially for static methods and do not to rely on null values. One exception only if it is the exact purpose of your method, for example ThrowIfNull or IsNullOrEmpty extension methods.
It doesn't really matter as long as you communicate the behavior well (so that the end-user knows what to expect).
Consider using the built-in XML Documentation Comments to communicate expected behavior.
/// <exception cref="ArgumentNullException">argument is null.</exception>
public string Example( string argument )
{
if ( argument == null )
throw new ArgumentNullException();
return argument.ToString();
}
See MSDN documentation for many examples:
DateTime.ParseExact Method (String, String, IFormatProvider)
Uri.FromHex Method
Suppose I have this:
class A
{
public void F()
{
//do stuff
}
}
If I then run the following code, what happens?
A a = null;
a.F();
You get a NullReferenceException. So I would say the proper way to write an equivalent extension method would be as follows.
class A
{
}
static class AExtensions
{
void F(this A a)
{
if (a == null)
{
throw new NullReferenceException();
}
//do stuff
}
}
However, .NET disagrees with me on this. The standard in .NET is to instead throw an ArgumentException - so it's probably best to do that instead.
Simple ; Create another method for String , say IsInValid()
public static bool IsInValid(this string s)
{
return (s == null) || (s.Length == 0);
}
use whereever you wanna check...
Furthermore, you can use this extension anywhere
Related
private static Matcher<T> EqualTo<T>(T item)
{
return new IsEqual<T>(item);
}
How do I modify the above method definition such that the following are valid/allowed.
EqualTo("abc");
EqualTo(4);
EqualTo(null); // doesn't compile. EqualTo<string>(null) does
Trying to port some Java code where null seems to be acceptable value for a T parameter.
Update
Thanks: for all the answers - especially Eamon and Jason. I didn't want the method calls to bother with type-inference. The following overload fixed it.
private static Matcher<object> EqualTo(object item)
{
return EqualTo<object>(item);
}
Actually the above question was a part of a larger puzzle. The end goal was for the following to work.
this.AssertThat(null, EqualTo(null));
this.AssertThat(null, Not(EqualTo("hi")));
this.AssertThat("hi", Not(EqualTo(null)));
Applied the same fix.. RFC. (Ignore the ugly extension method part - that's another problem. Wanted to have these methods in all test-fixtures without inheritance.)
public static void AssertThat<T>(this object testFixture, object actual, Matcher<T> matcher, string message = "")
{
AssertThat(anyObject, (T)actual, matcher, message);
}
public static void AssertThat<T, TSuper>(this object testFixture, T actual, Matcher<TSuper> matcher, string message = "") where T : TSuper
{
... check and assert
Consider the following method:
public bool IsNullString<T>(T item) {
return typeof(T) == typeof(string) && item == null;
}
Yes, this is a pathetically stupid method and using generics is pointless here, but you'll see the point in a moment.
Now consider
bool first = IsNullString<string>(null);
bool second = IsNullString<Foo>(null);
bool third = IsNullString(null);
In the first and second, the compiler can clearly distinguish the type of T (no inference is needed). In the third, how the compiler infer what T is? In particular, it can't distinguish between T == string and T == Foo, or any other type for that matter. Therefore, the compiler has to give you a compile-time error.
If you want to get around this, you either need to cast null
EqualTo((object)null);
or explicitly state the type
EqualTo<object>(null)
or define an overload
private static Matcher<object> EqualTo(object item) {
return new IsEqual<object>(item);
}
Not possible without explicitly specifying a T or doing a cast. Generics are compile time constructs and as such if the compiler can't figure out the type at compile time, then it won't compile (as you're seeing).
Since you can't do exactly what you are wanting to do, how about defining an EqualTo(object) overloaded method? That should allow your required syntax.
You may work around this limitation by using the following syntax:
EqualTo("abc");
EqualTo(4);
EqualTo(default(object));
//equivalently:
EqualTo((object)null);
default(T) is the value a field of type T has if not set. For reference types, it's null, for value types it's essentially memory filled with zero bytes (...which may mean different things for different types, but generally means some version of zero).
I try to avoid the null everywhere in my code nowadays. It hampers type inference elsewhere too, such as with the var declared field and in a ternary operator. For example, myArray==null ? default(int?) : myArray.Length is OK, but myArray==null ? null : myArray.Length won't compile.
Maybe implementing a non-generic EqualTo, which takes an Object as the argument type, would solve the issue of rewriting those code lines.
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");
I usually do this:
void Incoming(String str)
{
if (str == "")
{
}
}
But I've seen others' code do this:
void Incoming(String str)
{
if (str == String.Empty)
{
}
}
In my case I know str shouldn't be null. So would the following be a good idea instead, given it will cause an exception if the string is null rather than hiding the problem:
void Incoming(String str)
{
if (str.Length == 0)
{
}
}
And I've noticed this being used too, but this seems to accept the string might be null, rather than going and fixing the reason it is null. Is it a good idea to silently handle strings being null?
void Incoming(String str)
{
if (String.IsNullOrEmpty(str))
{
}
}
if(String.IsNullOrEmpty(str1))
{
//do stuff
}
Always use this!
What is the best way of testing that a string is empty?
Your last option String.IsNullOrEmpty(str) is best to do so. It checks for both condition
If string is null
If your string is equal to String.Empty i.e. "".
If the string should never be null, do an explicit null check before testing whether it's empty.
if (string == null) throw new Exception(); // ArgumentNullException, for example
if (string == "")
{
...
}
Generally you should not use Exceptions for System flow. So if the String can (but shouldn't) be null, then check for NullOrEmpty and fix it there.
Whats the matter for checking if it is NULL or Empty? Both will cause some fixing Code or you can throw your own "IHateNullStrings"-Exception.
If you want the total safety:
String.IsNullOrWhiteSpace
With this one you check
Null
Empty
Only WhiteSpace characters
Edit: Exception Flow is the path the program passes. Using exception for "Could happen"-things makes f.e. debugging way more complicated.
There is a huge discussion about this, f.e. :Why not use exceptions as regular flow of control?
Although you say str should not be null, you are relying on something external to adhere to that, which is not a good idea. Also, letting an exception be thrown in the if block is not a great idea because:
Exceptions are expense, so should be avoided where possible
The default exception is not going to give the caller much context as to what they have done wrong. So if you really need an exception, throw one yourself with something meaningful (I.E. ArgumentNullException) with a useful message
so with the above said you can either do a seperate null check:
if (str == null) throw new ArgumentNullException("str cannot be null");
or you can treat null and string.Empty as equal and use (which would be my default):
if (string.IsNullOrEmpty(str))
{
//do something
}
or you can even treat blank strings the same as null and empty by using:
if (string.IsNullOrWhiteSpace(str))
{
/do something
}
It largely depends on what your logic is when you get empty strings. However you should always be writing some defensive code to deal with arguments not fulfilling the pre-conditions
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.
edit 2015 This question and its answers are no longer relevant. It was asked before the advent of C# 6, which has the null propagating opertor (?.), which obviates the hacky-workarounds discussed in this question and subsequent answers. As of 2015, in C# you should now use Form.ActiveForm?.ActiveControl?.Name.
I've been thinking about the null propagation problem in .NET, which often leads to ugly, repeated code like this:
Attempt #1 usual code:
string activeControlName = null;
var activeForm = Form.ActiveForm;
if (activeForm != null)
{
var activeControl = activeForm.ActiveControl;
if(activeControl != null)
{
activeControlname = activeControl.Name;
}
}
There have been a few discussions on StackOverflow about a Maybe<T> monad, or using some kind of "if not null" extension method:
Attempt #2, extension method:
// Usage:
var activeControlName = Form.ActiveForm
.IfNotNull(form => form.ActiveControl)
.IfNotNull(control => control.Name);
// Definition:
public static TReturn IfNotNull<TReturn, T>(T instance, Func<T, TReturn> getter)
where T : class
{
if (instance != null ) return getter(instance);
return null;
}
I think this is better, however, there's a bit of syntactic messy-ness with the repeated "IfNotNull" and the lambdas. I'm now considering this design:
Attempt #3, Maybe<T> with extension method
// Usage:
var activeControlName = (from window in Form.ActiveForm.Maybe()
from control in window.ActiveControl.Maybe()
select control.Name).FirstOrDefault();
// Definition:
public struct Maybe<T> : IEnumerable<T>
where T : class
{
private readonly T instance;
public Maybe(T instance)
{
this.instance = instance;
}
public T Value
{
get { return instance; }
}
public IEnumerator<T> GetEnumerator()
{
return Enumerable.Repeat(instance, instance == null ? 0 : 1).GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
public static class MaybeExtensions
{
public static Maybe<T> Maybe<T>(this T instance)
where T : class
{
return new Maybe<T>(instance);
}
}
My question is: is this an evil abuse of extension methods? Is it better than the old usual null checks?
It's interesting that so many people independently pick the name IfNotNull, for this in C# - it must be the most sensible name possible! :)
Earliest one I've found on SO: Possible pitfalls of using this (extension method based) shorthand
My one (in ignorance of the above): Pipe forwards in C#
Another more recent example: How to check for nulls in a deep lambda expression?
There are a couple of reasons why the IfNotNull extension method may be unpopular.
Some people are adamant that an extension method should throw an exception if its this parameter is null. I disagree if the method name makes it clear.
Extensions that apply too broadly will tend to clutter up the auto-completion menu. This can be avoided by proper use of namespaces so they don't annoy people who don't want them, however.
I've played around with the IEnumerable approach also, just as an experiment to see how many things I could twist to fit the Linq keywords, but I think the end result is less readable than either the IfNotNull chaining or the raw imperative code.
I've ended up with a simple self-contained Maybe class with one static method (not an extension method) and that works very nicely for me. But then, I work with a small team, and my next most senior colleague is interested in functional programming and lambdas and so on, so he isn't put off by it.
Much as I'm a fan of extension methods, I don't think this is really helpful. You've still got the repetition of the expressions (in the monadic version), and it just means that you've got to explain Maybe to everyone. The added learning curve doesn't seem to have enough benefit in this case.
The IfNotNull version at least manages to avoid the repetition, but I think it's still just a bit too longwinded without actually being clearer.
Maybe one day we'll get a null-safe dereferencing operator...
Just as an aside, my favourite semi-evil extension method is:
public static void ThrowIfNull<T>(this T value, string name) where T : class
{
if (value == null)
{
throw new ArgumentNullException(name);
}
}
That lets you turn this:
void Foo(string x, string y)
{
if (x == null)
{
throw new ArgumentNullException(nameof(x));
}
if (y == null)
{
throw new ArgumentNullException(nameof(y));
}
...
}
into:
void Foo(string x, string y)
{
x.ThrowIfNull(nameof(x));
y.ThrowIfNull(nameof(y));
...
}
There's still the nasty repetition of the parameter name, but at least it's tidier. Of course, in .NET 4.0 I'd use Code Contracts, which is what I'm meant to be writing about right now... Stack Overflow is great work avoidance ;)
If you want an extension method to reduce the nested if's like you have, you might try something like this:
public static object GetProperty(this object o, Type t, string p)
{
if (o != null)
{
PropertyInfo pi = t.GetProperty(p);
if (pi != null)
{
return pi.GetValue(o, null);
}
return null;
}
return null;
}
so in your code you'd just do:
string activeControlName = (Form.ActiveForm as object)
.GetProperty(typeof(Form),"ActiveControl")
.GetProperty(typeof(Control),"Name");
I don't know if I'd want to use it to often due to the slowness of reflection, and I don't really think this much better than the alternative, but it should work, regardless of whether you hit a null along the way...
(Note: I might've gotten those types mixed up) :)
In case you're dealing with C# 6.0/VS 2015 and above, they now have a built-in solution for null propagation:
string ans = nullableString?.Length.ToString(); // null if nullableString == null, otherwise the number of characters as a string.
The initial sample works and is the easiest to read at a glance. Is there really a need to improve on that?
The IfNotNull solution is the best (until the C# team gives us a null-safe dereferencing operator, that is).
I'm not too crazy about either solution. What was wrong with ashorter version of the original:
string activeControlName = null;
if (Form.ActiveForm != null)
if (Form.ActiveForm.ActivControl != null) activeControlname = activeControl.Name;
If not this, then I would look at writing a NotNullChain or FluentNotNull object than can chain a few not null tests in a row. I agree that the IfNotNull extension method acting on a null seems a little weird - even though extension methods are just syntactic sugar.
I think Mark Synowiec's answer might be able to made generic.
IMHO, I think the C# core team should look at the this "issue", although I think there are bigger things to tackle.
Sure, original 2-nested IF is much more readable than other choices. But suggesting you want to solve problem more generally, here is another solution:
try
{
var activeForm = Form.ActiveForm; assumeIsNotNull(activeForm);
var activeControl = activeForm.ActiveControl; assumeIsNotNull(activeControl);
var activeControlname = activeControl.Name;
}
catch (AssumptionChainFailed)
{
}
where
class AssumptionChainFailed : Exception { }
void assumeIsNotNull(object obj)
{
if (obj == null) throw new AssumptionChainFailed();
}