Si no me equivoco, cada respuesta aquí denigra el hecho de que el método de extensión se puede invocar en una instancia nula, y debido a esto no admiten creer que es una buena idea.
Déjenme contar sus argumentos.
No creo EN ABSOLUTO que llamar a un método sobre un objeto que puede ser nulo es confuso. El hecho es que solo buscamos valores nulos en ciertas ubicaciones, y no el 100% del tiempo. Eso significa que hay un porcentaje de tiempo en el que cada llamada a un método que hacemos es potencialmente sobre un objeto nulo. Esto es entendido y aceptable. Si no fuera así, estaríamos verificando el nulo antes de cada llamada a un solo método.
Entonces, ¿cómo es confuso que una llamada de método en particular pueda estar ocurriendo en un objeto nulo? Mira el siguiente código:
var bar = foo.DoSomethingResultingInBar();
Console.Writeline(bar.ToStringOr("[null]"));
¿Estás confundido? Usted debería ser. Porque aquí está la implementación de foo:
public Bar DoSomethingResultingInBar()
{
return null; //LOL SUCKER!
}
Ver? Lees la muestra del código sin confundirte en absoluto. Usted entendió que, potencialmente, foo devolvería un nulo de esa llamada a método y la llamada a ToStringOr en bar
resultaría en un NRE. ¿Tu cabeza dio vueltas? Por supuesto no. Se entiende que esto puede suceder. Ahora, ese método ToStringOr no es familiar. ¿Qué haces en estas situaciones? O lee los documentos sobre el método o examina el código de la llamada. Aquí está:
public static class BarExtensions
{
public static string ToStringOr(this bar, string whenNull)
{
return bar == null ? whenNull ?? "[null]" : bar.ToString();
}
}
Confusing? Por supuesto no. Es obvio que el desarrollador quería un método abreviado para comprobar si bar
es nulo y sustituirlo por una cadena no nula. Hacer esto puede reducir drásticamente el código y aumentar la legibilidad y la reutilización del código. Por supuesto, podrías hacer esto de otras maneras, pero de esta manera no sería más confuso que cualquier otro. Por ejemplo:
var bar = foo.DoSomethingResultingInBar();
Console.Writeline(ToStringOr(bar, "[null]"));
Cuando se encuentra con este código, ¿qué tiene que diferenciar de la versión original? Todavía tiene que examinar el código, aún debe determinar su comportamiento cuando bar
es nulo. Aún tienes que lidiar con esta posibilidad.
¿Los métodos de extensión son confusos? Solo si no los entiendes Y, francamente, lo mismo se puede decir de CUALQUIER parte del lenguaje, desde delegados hasta lambdas.
Estoy de acuerdo con su primer punto, pero no del todo el segundo. Creo que hay un problema de inconsistencia que tenemos que enfrentar y no podemos hacer nada al respecto. Podríamos aprender a gustar y, al menos, aprovechar las ventajas (a la vez que tenemos una idea de lo que realmente está sucediendo). Por cierto, hay un problema de inconsistencia similar en 'Nullable .Equals()' cuando se llama en 'null'. –
Sí nullable hace trucos como este hoy. Pero mira cuánta gente confunde. Parece que tenemos una pregunta emergente aquí una vez a la semana sobre "por qué los elementos nullables funcionan de forma divertida con operaciones booleanas si un valor es nulo". Voy a responder a la primera parte con una edición. Se agotó el espacio en el campo de comentarios – JaredPar
¡LOL! Este Nullable estaba condenado porque cambió el comportamiento en beta. ¡Creo que arruinó el equipo de SQL/CLR en ese momento! No estoy hablando del método 'String.IsNullOrEmpty' en particular. Todos los métodos que podrían funcionar con 'null' son aceptables y tienen sentido como un buen método de extensión. Mi opinión es que deberíamos aceptar que la sintaxis '.Method()' es más que una simple llamada al método de instancia. Por ejemplo, podríamos tener el método XmlAttribute.ValueEquals ("xyz") para eludir la comprobación nula en LINQ to XML. No lo sé. Estoy pensando en tu punto. Por cierto, odio esa cosa global de "usar". –