2009-03-15 14 views
14

Compruebo continuamente los campos de cadena para comprobar si son nulos o están en blanco.String.IsNullOrBlank Método de extensión

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

Para ahorrarme un poco de tipeo ¿es posible crear un método de extensión para la clase String que tenga el mismo efecto? Entiendo cómo se pueden agregar los métodos de extensión para una instancia de clase, pero ¿qué pasa con agregar un método de extensión estática a una clase?

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

Respuesta

35

Se podría hacer:

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

Y luego llamarlo así:

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

Esto funciona porque C# le permite llamar método de extensión en los casos nulos.

+7

Bill Wagner en "Más eficaz C#" recomienda no hacer que las funciones de extensión funcionen con instancias nulas (págs.183) La razón es que la extensión se supone que los métodos se parecen a las llamadas a métodos, y no se puede llamar a un método con una instancia nula. –

+1

Curiosamente, C# no le permite llamar a un método con una instancia nula ya que emite una instrucción callvirt IL. IL si realiza una llamada a través de la instrucción "call" puede llamar en una instancia nula. – Sean

+13

@dan - No creo que un método t El sombrero implica una comprobación nula en su nombre es un mal uso para los métodos de extensión. – Maslow

2

¿Se pueden agregar métodos estáticos a las clases existentes? La respuesta es no, y el valor sería bastante bajo, porque aún necesitaría saber qué nombre de clase escribir primero; con los métodos de extensión, la ventaja es que comienza con un nombre de variable y la autocompletación le muestra cosas que le son aplicables.

Otro punto que se suele mencionar es que los métodos de extensión siempre deben arrojar una excepción lo antes posible si su primer argumento es nulo. Sin embargo, creo que esa regla es exagerada si el método menciona en su nombre que está diseñado para verificar null.

El verdadero problema que tiene es que quiere ejecutar código de forma clara y legible después de buscar una referencia nula. Una forma de capturar ese patrón es en my answer to this question.

+0

No es lo mismo, IsNullOrEmpty no comprueba cadenas que contienen únicamente caracteres de espacio en blanco. – Joe

+0

Bien manchado, fijo. –

+0

Y también, si llama a Trim() y la cadena fue nula, obtendrá una NullReferenceException. Lo siento, no tiene mucho valor en la respuesta y también es engañoso, así que -1. – erikkallen

6

Usted puede utilizar con seguridad un método de extensión en la instancia:

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

Los casos de prueba:

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

se ve un poco raro sin embargo, y en lugar de eso se daría cuenta de por qué sus cuerdas necesitan ser revisado en este caso tan a menudo. Si los arreglas en la fuente, ¡no tendrás que ser tan paranoico sobre ellos más tarde!

-2
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 + ""; 
    } 
+0

No creo que me guste tanto. La semántica de IsNull e IsNotNull es sorprendente. ¿Por qué agrega la cadena. Vacío a o en ToStr? –

+0

Es más útil para objetos (por ejemplo, cuando se necesita hacer algo con Eval ("blalblabla")), pero también se pueden usar cadenas. ¿Por qué no te gusta esto? – omoto

+0

Conceptualmente, (o == null)! = (O.ToStr == string.empty). Si quiero probar una referencia para null, me conviene probarla para null. (No soy tu vindicador, solo digo que creo que entiendo por qué sucedió). –

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

o

public static bool IsNullOrEmpty(this String value, bool checkTrimmed) 
{ 
    var b = String.IsNullOrEmpty(value); 
    return checkTrimmed ? (b && value.Trim().Length > 0) : b; 
} 
+0

No funcionará si la cadena que se prueba es nula ya que el método Trim() necesita un objeto. – sipwiz

+0

Tienes razón. He editado mi código – abatishchev

+0

IsNullOrEmptyTrimmed (null); Creo que obtiene un error porque value.Length for value es null, throw NullReferenceException, ¿no? – Kiquenet

0

Bill Wagner en más eficaz C# recomienda en contra de hacer funciones de extensión trabajan con casos nulos (pp. 183).

La razón es que los métodos de extensión deben parecerse a las llamadas a métodos, y no puede llamar a un método con una instancia null.

0

Con un poco de ingenio, haces que parezca que haya agregado a la clasecadena en cualquier un archivo cs:

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

(nota, esto es no un método de extensión , mira mi comentario).

Entonces, en algún otro archivo CS:

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."); 
      } 
     } 
... 

Aviso la sintaxis "deseado" de String.IsNullOrBlank(). No estoy necesariamente sugiriendo que realmente hagas las cosas de esta manera, solo señalando cómo puedes configurar las cosas para hacer que tu código funcione.

+0

Eso introduce una gran confusión de nombres. Ahora los codificadores deberán verificar si esa cadena es una JDanielSmith.String o una System.String ... ugh! – code4life

+0

"No estoy necesariamente sugiriendo que realmente haga las cosas de esta manera ..." –

+0

El método de extensión descrito anteriormente es claramente más comprensible. @ code4life tiene razón: ¡Uf! – dlchambers

1

Una sobrecarga a las respuestas existentes podrían ser:

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

sería útil si sólo desea ejecutar código dado un valor válido.

No es un ejemplo súper útil, pero sólo muestra el uso:

Name.IsNullOrBlank(name=>Console.WriteLine(name)); 
+0

cualquier muestra usando su método? – Kiquenet

+0

@alhambraeidos - hecho, o ¿estabas buscando un ejemplo que muestre un escenario más específico/útil? – Maslow

15

Sé que esto es una cuestión de edad, pero desde que fue golpeado y que no ha sido ya mencionado, a partir de .NET 4.0, simplemente puede usar String.IsNullOrWhiteSpace method para lograr el mismo resultado.

+1

String.IsNullOrWhiteSpace es un método estático, la extensión es más conveniente de usar. Incluso String.IsNullOrEmpty es más fácil de usar como Método de extensión -ver http://thomasfreudenberg.com/blog/archive/2008/01/25/string-isnullorempty-as-extension-method.aspx –

1

Un poco tarde. Pero también puedes poner el código para lanzar una excepción en un método de extensión también. Tengo dos métodos (para ArgumentNullException y NullReferenceException).

// strings 
public static bool NullBlankCheck(this string s, string message = "", 
    bool throwEx = true) 
{ 
    return Check<NullReferenceException>(s.IsNullOrBlank(), throwEx, message); 
} 
public static bool NullBlankCheckArgument(this string s, string message = "", 
    bool throwEx = true) 
{ 
    return Check<ArgumentException>(s.IsNullOrBlank(), throwEx, message); 
} 

private static bool Check<T>(bool isNull, bool throwEx, string exceptionMessage) 
    where T : Exception 
{ 
    if (throwEx && isNull) 
     throw Activator.CreateInstance(typeof(T), exceptionMessage) as Exception; 
    return isNull; 
} 

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

pruebas NUnit:

Assert.Throws<NullReferenceException>(() => 
{ 
    "".NullEmptyCheck(); 
}); 
Assert.Throws<ArgumentException>(() => 
{ 
    "".NullEmptyCheckArgument(); 
}); 

Y luego usarlo como:

public void Method(string someStr) 
{ 
    someStr.NullBlankCheckArgument(); 
    // do something 
    var str = someMethod(); 
    str.NullBlankCheck(); 
} 
Cuestiones relacionadas