Mientras estudiaba el delegado, que en realidad es una clase abstracta enDelegate.cs
, vi el siguiente método en el que no entiendo
- Por qué se usa el valor de retorno
?
aunque ya es una referencia ( clase ) ?[]?
significado en el parámetro
¿Podrías explicar?
public static Delegate? Combine(params Delegate?[]? delegates)
{
if (delegates == null || delegates.Length == 0)
return null;
Delegate? d = delegates[0];
for (int i = 1; i < delegates.Length; i++)
d = Combine(d, delegates[i]);
return d;
}
c#
.net
null-coalescing-operator
nullable-reference-types
null-coalescing
snr - Restablece a Monica
fuente
fuente
Respuestas:
Explicación paso a paso:
params Delegate?[] delegates
- Es una matriz de nulosDelegate
params Delegate?[]? delegates
- Todo el conjunto puede ser anulableDado que cada parámetro es del tipo
Delegate?
y devuelve un índice de laDelegate?[]?
matriz, tiene sentido que el tipo de retorno sea de loDelegate?
contrario el compilador devolvería un error como si estuviera retirándose yint
de un método que devuelve una cadena.Podría cambiar, por ejemplo, su código para devolver un
Delegate
tipo como este:fuente
?
aunque ya es del tipo de referencia (clase)?
exactamente por la misma razón por la cual el valor del argumento usa el?
. Si entiendes lo último, automáticamente entiendes lo primero. Debido a que el método puede devolver nulo , como el parámetro puede aceptar nulo . Es decir, ambos pueden contener nulo .Since each parameter is of the type Delegate? and you return an index of the Delegate?[]? array, then it makes sense that the return type is Delegate?
Foo?
tiene unaHasValue
propiedad ordenada , mientrasFoo
que debe== null
verificarse (4) Se comunica a los desarrolladores que leen la firma del método que los resultados nulos son posibles, esperados y correctos. (5) El código parece estar escrito por alguien que es muy aficionado a la nulabilidad y es explícito al respecto.Tipos de referencia anulables son nuevos en C # 8.0, no existían antes.
Es una cuestión de documentación y de cómo se producen las advertencias en tiempo de compilación.
La excepción "objeto no establecido en una instancia de un objeto" es bastante común. Pero esta es una excepción en tiempo de ejecución, ya se puede descubrir parcialmente en tiempo de compilación.
Para un regular
Delegate d
siempre puedes llamares decir, puede codificarlo, en el momento de la compilación no sucederá nada. Puede generar excepciones en tiempo de ejecución.
Mientras que para un nuevo
Delegate? p
este Códigoproducirá una advertencia del compilador.
CS8602: Dereference of a possibly null reference
a menos que escribas:lo que significa, llamar solo si no es nulo.
Entonces, documentar una variable puede contener nulo o no. Genera advertencias antes y puede evitar múltiples pruebas de nulo. ¿Lo mismo que tienes para int e int ?. Usted sabe con certeza, uno no es nulo, y sabe cómo convertir uno a otro.
fuente
Delegate
no es nula. Simplemente finge estar seguro (lo cual es lo suficientemente bueno en la mayoría de los casos).int
nunca puede ser nulo. Si tiene unDelegate
puede ser nulo (por varias razones, por ejemplo, reflexión). Por lo general, es seguro asumir queDelegate
(en C # 8 con NRT habilitado) no es nulo, pero nunca se sabe con certeza (de dóndeint
estamos seguros).En C # 8, uno debe marcar explícitamente los tipos de referencia como anulables.
Por defecto, esos tipos no pueden contener nulos, algo similares a los tipos de valor. Si bien esto no cambia la forma en que funcionan las cosas debajo del capó, el verificador de tipo requerirá que lo haga manualmente.
El código dado se refactoriza para funcionar con C # 8, pero no se beneficia de esta nueva característica.
Aquí hay un ejemplo de un código actualizado (que no funciona, solo una idea) que aprovecha esta característica. Nos salvó de una verificación nula y simplificó un poco este método.
fuente
those types are not able to contain null
, tenga en cuenta que genera una advertencia del compilador , no un error. El código se ejecutará bien (aunque podría generar NullReferenceExceptions). Esto se hace teniendo en cuenta la compatibilidad con versiones anteriores.