generate - params comments c#
¿Qué tan útil es C#''s? ¿operador? (13)
?? es un operador de verificación nulo, en efecto.
La razón por la que su código se mete en problemas es que si "someObject es nulo, .someMember es una propiedad en un objeto nulo. Primero tendrá que verificar algunos objetos en null.
EDITAR:
Debería añadir que sí, me parece ?? para ser muy útil, especialmente en el manejo de entrada de base de datos, especialmente de LINQ, pero también en otros casos. Lo uso mucho.
¿Así que me ha intrigado el ?? operador, pero aún no han podido utilizarlo. Usualmente pienso en eso cuando estoy haciendo algo como:
var x = (someObject as someType).someMember;
Si someObject es válido y someMember es nulo, podría hacer
var x = (someObject as someType).someMember ?? defaultValue;
pero casi invariablemente me meto en problemas cuando someObject es nulo, y ?? no me ayuda a hacer esto más limpio que hacer la comprobación nula yo mismo.
¿Qué usos han encontrado para ustedes? en situaciones practicas?
A menudo lo uso para objetos con instancias perezosas en propiedades, por ejemplo,
public MyObject MyProperty
{
get
{
return this.myField ?? (this.myField = new MyObject());
}
}
Esto se aprovecha del hecho de que en C # una asignación es una expresión, por lo que puede asignar y usar el resultado de la expresión (el valor asignado), todo en la misma declaración. Todavía me siento un poco sucio acerca de este patrón de código, pero es más terso que la alternativa (a continuación), por lo que casi gana.
public MyObject MyProperty
{
get
{
if (this.myField == null)
{
this.myField = new MyObject();
}
return this.myField;
}
}
A menudo parece ser una buena idea reemplazar un poco de sintaxis con una forma más compacta. Pero, por lo general, solo se confunde el código sin ganar nada. Los estándares modernos abogan por nombres de variables más extensos y descriptivos y el uso de estilos de diseño más detallados para hacer que el código sea más legible y más fácil de mantener.
Si voy a entrenar mi cerebro para que analice rápidamente, necesito encontrar una situación en la que muestre una clara ventaja, algo que no se pueda hacer de otra manera, o en algún lugar que ahorre una cantidad significativa de escritura.
¿Y aquí es donde? se cae para mi Es útil con poca frecuencia y?: Y si / else son alternativas tan rápidas y legibles que realmente no tiene sentido usar una sintaxis diferente que no logre nada nuevo.
a = b ?? c ?? d ?? mi; suena genial. ¡Pero nunca he necesitado hacer eso!
Lo que encuentro irritante es que quiero usar ??, pero cada vez que pienso "ooh, tal vez pueda usar" aquí ", me doy cuenta de que no quiero usar el objeto en sí, sino un miembro de él. .
nombre = (usuario == nulo)? "doe": usuario.
Y desafortunadamente, ?? no ayuda aqui
Al igual que un FYI, el operador ternario genera una secuencia diferente de IL a partir del operador de unión nula. El primero se ve algo así:
// string s = null;
// string y = s != null ? s : "Default";
ldloc.0
brtrue.s notnull1
ldstr "Default"
br.s isnull1
notnull1: ldloc.0
isnull1: stloc.1
Y este último luce así:
// y = s ?? "Default";
ldloc.0
dup
brtrue.s notnull2
pop
ldstr "Default"
notnull2: stloc.1
En base a esto, diría que el operador de fusión nula está optimizado para su propósito y no es solo azúcar sintáctica.
El ??
operador es como el método de coalesce en SQL, obtiene el primer valor no nulo.
var result = value1 ?? value2 ?? value3 ?? value4 ?? defaultValue;
En su caso, puede crear DefaultObject como una propiedad estática y usar como a continuación ...
var x = (someObject as someType ?? someType.DefaultObject).someMember;
Donde su DefaultObject devolverá un objeto estático, de solo lectura.
Como EventArgs.Empty, String.Empty, etc ...
Estoy de acuerdo contigo en que? el operador suele ser de uso limitado: es útil proporcionar un valor de recuperación si algo es nulo, pero no es útil para evitar una excepción de referencia nula en los casos en los que desea continuar explorando las propiedades o métodos de un método a veces. referencia nula.
En mi humilde opinión, ¿qué se necesita mucho más que ?? es un operador de "anulación de referencia nula" que le permite encadenar cadenas largas de propiedades y / o métodos, por ejemplo, ab().cd().e
sin tener que probar cada paso intermedio en busca de nulidad. El lenguaje Groovy tiene un operador de navegación segura y es muy práctico.
Afortunadamente, parece que el equipo de C # es consciente de esta brecha de características. Consulte esta sugerencia de connect.microsoft.com para que el equipo de C # agregue un operador de anulación de nulos al lenguaje C #.
Recibimos una gran cantidad de solicitudes de características similares a esta. Los "?." La versión mencionada en la discusión de la comunidad es la más cercana a nuestros corazones: te permite realizar pruebas de nulo en cada "punto" y se compone bien con el existente. operador:
a B C ?? re
Significa que si cualquiera de a, ab o abc es nulo, use d en su lugar.
Estamos considerando esto para un lanzamiento futuro, pero no estará en C # 4.0.
Gracias de nuevo,
Mads Torgersen, C # Idioma PM
Si también desea esta función en C #, ¡agregue sus votos a la sugerencia en el sitio de conexión! :-)
Una solución que utilizo para evitar la falta de esta característica es un método de extensión como el que se describe en esta publicación del blog , para permitir un código como este:
string s = h.MetaData
.NullSafe(meta => meta.GetExtendedName())
.NullSafe(s => s.Trim().ToLower())
Este código devuelve h.MetaData.GetExtendedName().Trim().ToLower()
o devuelve nulo si h, h.MetaData o h.MetaData.GetExtendedName () es nulo. También he extendido esto para verificar si hay cadenas nulas o vacías, o colecciones nulas o vacías. Aquí está el código que utilizo para definir estos métodos de extensión:
public static class NullSafeExtensions
{
/// <summary>
/// Tests for null objects without re-computing values or assigning temporary variables. Similar to
/// Groovy''s "safe-dereference" operator .? which returns null if the object is null, and de-references
/// if the object is not null.
/// </summary>
/// <typeparam name="TResult">resulting type of the expression</typeparam>
/// <typeparam name="TCheck">type of object to check for null</typeparam>
/// <param name="check">value to check for null</param>
/// <param name="valueIfNotNull">delegate to compute if check is not null</param>
/// <returns>null if check is null, the delegate''s results otherwise</returns>
public static TResult NullSafe<TCheck, TResult>(this TCheck check, Func<TCheck, TResult> valueIfNotNull)
where TResult : class
where TCheck : class
{
return check == null ? null : valueIfNotNull(check);
}
/// <summary>
/// Tests for null/empty strings without re-computing values or assigning temporary variables
/// </summary>
/// <typeparam name="TResult">resulting type of the expression</typeparam>
/// <param name="check">value to check for null</param>
/// <param name="valueIfNotNullOrEmpty">delegate to compute non-null value</param>
/// <returns>null if check is null, the delegate''s results otherwise</returns>
public static TResult CheckNullOrEmpty<TResult>(this string check, Func<string, TResult> valueIfNotNullOrEmpty)
where TResult : class
{
return string.IsNullOrEmpty(check) ? null : valueIfNotNullOrEmpty(check);
}
/// <summary>
/// Tests for null/empty collections without re-computing values or assigning temporary variables
/// </summary>
/// <typeparam name="TResult">resulting type of the expression</typeparam>
/// <typeparam name="TCheck">type of collection or array to check</typeparam>
/// <param name="check">value to check for null</param>
/// <param name="valueIfNotNullOrEmpty">delegate to compute non-null value</param>
/// <returns>null if check is null, the delegate''s results otherwise</returns>
public static TResult CheckNullOrEmpty<TCheck, TResult>(this TCheck check, Func<TCheck, TResult> valueIfNotNullOrEmpty)
where TCheck : ICollection
where TResult : class
{
return (check == null || check.Count == 0) ? null : valueIfNotNullOrEmpty(check);
}
}
He tenido exactamente el mismo problema que usted, pero en el espacio de uso de LinqToXML puede que no haya una etiqueta en el documento, por lo tanto, ¿usarlo ??
no es viable para vender la propiedad en esa etiqueta.
Dado que no existen variables globales en C #, todo está en una clase, así que, como usted, encuentro eso. es en su mayoría inútil.
Incluso un simple captador de propiedades como:
MyObject MyObj() { get { return _myObj ?? new MyObj(); } }
Es probable que esté mejor servido por un inicializador ...
Me imagino que al igual que en SQL sería algo útil en las consultas de Linq, pero no puedo derivar una en este momento.
Lo he estado usando con cosas de App.Config
string somethingsweet = ConfigurationManager.AppSettings["somesetting"] ?? "sugar";
Lo más útil es cuando se trata de tipos anulables.
bool? whatabool;
//...
bool realBool = whatabool ?? false;
sin ?? necesitarías escribir lo siguiente, que es mucho más confuso.
bool realbool = false;
if (whatabool.HasValue)
realbool = whatabool.Value;
Encuentro a este operador muy útil para los tipos anulables, pero aparte de eso, no lo uso mucho. Definitivamente un atajo fresco.
Lo uso para trabajar con métodos que pueden devolver nulo en condiciones normales de funcionamiento.
por ejemplo, digamos que tengo una clase contenedora que tiene un método Get que devuelve nulo si el contenedor no contiene una clave (o tal vez nula es una asociación válida). Entonces podría hacer algo como esto:
string GetStringRep(object key) {
object o = container.Get(key) ?? "null";
return o.ToString();
}
Claramente, estas dos secuencias son equivalentes:
foo = bar != null ? bar : baz;
foo = bar ?? baz;
El segundo es simplemente más conciso.
Por lo general lo uso para cadenas o tipos anulables.
string s = someString ?? "Default message";
es más fácil que
string s;
if(someString == null)
s = "Default Message";
else
s = someString;
o
string s = someString != null ? someString : "Default Message";
Utilizo el operador de unión nula a menudo al analizar cadenas en otros tipos de datos. Tengo un conjunto de métodos de extensión que envuelven cosas como Int32.TryParse y devuelvo un int anulable en lugar de exponer un parámetro de salida al resto de mi código. Entonces puedo analizar una cadena y proporcionar un valor predeterminado si el análisis falló, en una sola línea de código.
// ToNullableInt(), is an extension method on string that returns null
// if the input is null and returns null if Int32.TryParse fails.
int startPage = Request.QueryString["start"].ToNullableInt() ?? 0;