views:

707

answers:

7

I continuously check string fields to check if they are null or blank.

if(myString == null || myString.Trim().Length == 0)
{
    throw new ArgumentException("Blank strings cannot be handled.");
}

To save myself a bit of typing is it possible to create an extension method for the String class that would have the same effect? I understand how extension methods can be added for a class instance but what about adding a static extension method to a class?

if(String.IsNullOrBlank(myString))
{
    throw new ArgumentException("Blank strings cannot be handled.");
}
+1  A: 

Can you add static methods to existing classes? The answer is no, and the value would be pretty thin, because you'd still need to know which class name to type first; with extension methods, the advantage is that you start with a variable name and autocompletion shows you things that are applicable to it.

Another point often made is that extension methods should always throw an exception as soon as possible if their first argument is null. However, I think that rule is overkill if the method mentions in its name that it is designed to check for null.

The real problem you have is that you want to neatly and readably run some code after checking for a null reference. One way to capture that pattern is in my answer to this question.

Daniel Earwicker
It's not the same, IsNullOrEmpty doesn't check for strings that contain only whitespace characters.
Joe
Well spotted, fixed.
Daniel Earwicker
And also, if you call Trim() and the string was null, you will get a NullReferenceException. Sorry, not much of value in the answer and also misleading so -1.
erikkallen
The problem is you can't Trim till you check if it's null which is back to square one :(. Guess I could just create a new static class and call the method to that instead just would have been nice to have it on the String intellisense.
sipwiz
I've removed that first part altogether, I agree it was misleading.
Daniel Earwicker
+20  A: 

You could do:

public static bool IsNullOrBlank(this String text)
{
  return text==null || text.Trim().Length==0;
}

And then call it like this:

if(myString.IsNullOrBlank())
{
  throw new ArgumentException("Blank strings cannot be handled.");
}

This works because C# allows you to call extension method on null instances.

Sean
Bill Wagner in "More Effective C#" recommends against making extension functions work with null instances (pp. 183).The reason is that extension methods are supposed to look like method calls, and you can't call a method with a null instance.
Dan
Interestingly, C# doesn't allow you to call a method with a null instance as it emits a callvirt IL instruction. However, in IL if you make a call via the "call" instruction you can call on a null instance.
Sean
@dan - I don't think that a method that implies a null check in its name is a bad use for extension methods.
Maslow
+4  A: 

You can safely use an extension method on the instance:

public static class StringExtensions
{
    public static bool IsNullOrBlank(this string s)
    {
        return s == null || s.Trim().Length == 0;
    }
}

Test cases:

string s = null;
Assert.IsTrue(s.IsNullOrBlank());
s = " ";
Assert.IsTrue(s.IsNullOrBlank());

It looks a bit weird though, and I would instead figure out why your strings need to be checked for this case so often. If you fix them at the source, you won't have to be so paranoid about them later!

Jim Arnold
A: 
public static bool IsNull(this object o)
 {
  return string.IsNullOrEmpty(o.ToStr());
 }
 public static bool IsNotNull(this object o)
 {
  return !string.IsNullOrEmpty(o.ToStr());
 }
 public static string ToStr(this object o)
 {
  return o + "";
 }
omoto
I don't think I like this very much. The semantics of IsNull and IsNotNull are surprising. Why do you add the string.Empty to o in ToStr?
Greg D
It's more useful for objects(for example when need to do something with Eval("blalblabla")), but for strings could be used too. Why you don't like this?
omoto
Conceptually, (o == null) != (o.ToStr == string.empty). If I want to test a reference for null, I'm better off just testing it for null. (I'm not your downvote, just saying that I think I understand why it happened.)
Greg D
+2  A: 

Rewrite Microsoft code a bit:

public static bool IsNullOrEmptyTrimmed(string value)
{
  value = (value != null) ? value.Trim() : value 
  return (value.Length == 0);
}

or my own way:

public static bool IsNullOrEmpty(this String value, bool checkTrimmed)
{
  var b = String.IsNullOrEmpty(value);
  return checkTrimmed ? (b && value.Trim().Length > 0) : b;
}
abatishchev
Won't work if the string being tested is null since the Trim() method needs an object.
sipwiz
You're right. I have edited my code
abatishchev
A: 

With a few tricks, you make it look like you've added to the String class in any one cs file:

namespace JDanielSmith
{
    public static class String
    {
     public static bool IsNullOrBlank(string text)
     {
      return text == null || text.Trim().Length == 0;
     }
    }
}

(note, this is not an extension method, see my comment).

Then, in some other CS file:

using String = JDanielSmith.String;
namespace Foo.Bar.Baz
{
    class Program
    {
     static void test(string myString)
     {
      if (String.IsNullOrBlank(myString))
      {
       throw new ArgumentException("Blank strings cannot be handled.");
      }
     }
...

Notice the "desired" syntax of String.IsNullOrBlank(). I'm not necessarily suggesting that you actually do things this way, just pointing out how you could set things up to make your code work.

Dan
A: 

An overload to the existing answers could be:

public static bool IsNullOrBlank(this String text,Action<String> doWhat)
{
  if (text!=null && text.Trim().Length>0)
    doWhat(text);
}

Would be helpful if you only want to run code given a valid value.

Maslow