c# - recuento - siembra y aislamiento de microorganismos




En C#, ¿qué sucede cuando llama a un método de extensión en un objeto nulo? (5)

¿Se llama al método con un valor nulo o da una excepción de referencia nula?

MyObject myObject = null;
myObject.MyExtensionMethod(); // <-- is this a null reference exception?

Si este es el caso, ¿nunca tendré que revisar mi parámetro 'this' para nulo?


Como han señalado otros, llamar a un método de extensión en una referencia nula hace que este argumento sea nulo y no suceda nada más especial. Esto da lugar a una idea de utilizar métodos de extensión para escribir cláusulas de protección.

Puede leer este artículo para ver ejemplos: Cómo reducir la complejidad ciclomática: cláusula de la Guardia La versión corta es la siguiente:

public static class StringExtensions
{
    public static void AssertNonEmpty(this string value, string paramName)
    {
        if (string.IsNullOrEmpty(value))
            throw new ArgumentException("Value must be a non-empty string.", paramName);
    }
}

Este es el método de extensión de clase de cadena que se puede llamar en referencia nula:

((string)null).AssertNonEmpty("null");

La llamada funciona bien solo porque el tiempo de ejecución llamará con éxito el método de extensión en referencia nula. Luego puede usar este método de extensión para implementar cláusulas de protección sin sintaxis desordenada:

    public IRegisteredUser RegisterUser(string userName, string referrerName)
    {

        userName.AssertNonEmpty("userName");
        referrerName.AssertNonEmpty("referrerName");

        ...

    }

Como ya descubrió, dado que los métodos de extensión son simplemente métodos estáticos glorificados, se null con referencias null pasadas, sin que se lance una NullReferenceException . Pero, dado que parecen ser métodos de instancia para el llamante, también deben comportarse como tales. Entonces, la mayoría de las veces, debe comprobar this parámetro y lanzar una excepción si es null . Está bien no hacer esto si el método cuida explícitamente null valores null y su nombre lo indica debidamente, como en los ejemplos a continuación:

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

También he escrito una entrada de blog sobre esto hace algún tiempo.


Eso funcionará bien (sin excepción). Los métodos de extensión no usan llamadas virtuales (es decir, usan la instrucción "call" il, no "callvirt"), por lo que no hay una comprobación nula a menos que la escriba usted mismo en el método de extensión. Esto es realmente útil en algunos casos:

public static bool IsNullOrEmpty(this string value)
{
    return string.IsNullOrEmpty(value);
}
public static void ThrowIfNull<T>(this T obj, string parameterName)
        where T : class
{
    if(obj == null) throw new ArgumentNullException(parameterName);
}

etc

Fundamentalmente, las llamadas a llamadas estáticas son muy literales, es decir,

string s = ...
if(s.IsNullOrEmpty()) {...}

se convierte en:

string s = ...
if(YourExtensionClass.IsNullOrEmpty(s)) {...}

Donde obviamente no hay cheque nulo.


Hay pocas reglas de oro cuando quieres que tu texto sea legible y vertical.

  • Uno vale la pena decir de Eiffel que el código específico encapsulado en un método debería funcionar contra alguna entrada, ese código es viable si se cumplen algunas condiciones previas y asegura una salida esperada

En su caso, DesignByContract está roto ... va a realizar alguna lógica en una instancia nula.


Además de la respuesta correcta de Marc Gravell.

Podría recibir una advertencia del compilador si es obvio que este argumento es nulo:

default(string).MyExtension();

Funciona bien en el tiempo de ejecución, pero produce la advertencia "Expression will always cause a System.NullReferenceException, because the default value of string is null" .





extension-methods