c# - operador - null coalescing operator php
¿Hay alguna forma abreviada de devolver valores que podrían ser nulos? (11)
Aquí hay una mejor idea:
evitar que
_rows
sea
null
.
Haz que tu constructor inicialice la variable:
public MyClass()
{
this._rows = new List<Row>();
}
y tu propiedad es solo
get
{
return this._rows;
}
Asegúrese de que si necesita "borrar" la variable, siempre llame a su método
Clear
o asigne una nueva lista vacía en lugar de asignar
null
.
Tal vez codifique esa operación en un método si realmente necesita que sea clara y consistente en toda la clase.
Esto es
mucho
más lógico.
Si su variable nunca debería ser
null
,
nunca debería ser
null
.
También evita claramente tanto el condicional como el problema de tener un estado de modificación getter.
¿Cómo puedo escribir una abreviatura del siguiente escenario?
get
{
if (_rows == null)
{
_rows = new List<Row>();
}
return _rows;
}
Así por ejemplo:
get{ return _rows ?? (_rows = new List<Row>()); }
Como han dicho otros, puede usar el operador de fusión nula en este escenario.
get
{
return _rows ?? (_rows = new List<Row>());
}
Vale la pena señalar que este es el tipo de cambio que ReSharper es excelente para sugerir (lo llaman una quick-fix ).
En su ejemplo, colocará un pequeño garabato debajo de la instrucción
if
.
Al pasar el cursor sobre él, se muestra una
suggestion
de cómo se podría cambiar / simplificar el código.
Un par de clics más tarde y se implementa el cambio.
Este es el patrón de inicialización diferida, por lo que la forma más sencilla sería utilizar la clase Lazy<T> .
class Foo
{
Lazy<List<Row>> _rows;
public Foo()
{
_rows = new Lazy(() => new List<Row>());
}
public List<Row> Rows
{
get { return _rows.Value; }
}
}
Esto tiene la ventaja adicional de que no "contamina" al getter con la lógica de inicialización.
Puede hacerlo de cualquiera de las siguientes maneras:
- Operador condicional (? :)
- Operador de fusión nula (??)
Con operador condicional
get {
return _rows == null ? new List<Row>() : _rows;
}
Operador de fusión nula
get {
return _rows ?? new List<Row>();
}
Si desea que su código se comporte como su código actual, inicializando perezosamente su campo de respaldo cuando se accede a la propiedad, entonces sí, puede acortarlo.
Puede cambiar el nombre de su campo de respaldo, ya que la respuesta ya se utiliza
??
para poner todo en una sola expresión, y cuando tenga esa única expresión, use la nueva sintaxis de propiedad de C # 6 para evitar escribir
get
y
return
:
List<Row>_;List<Row> Rows=>_??(_=new List<Row>());
Con suerte, mucho antes de llegar a este punto, verá que ha convertido un código fácil de entender que hace exactamente lo que quiere en un desastre horrible que nunca querría mantener.
Simplemente mantenga su código exactamente como está. Puede hacerlo más corto, como se muestra, pero eso no lo hace mejor.
Si el problema es que lleva más tiempo escribir, porque sigue escribiendo el mismo código una y otra vez, muchos IDE proporcionan alguna característica para insertar plantillas, fragmentos o cualquier término que utilicen para ello. Esto le permite definir algo en la línea de
{Type} {Field};
public {Type} {Property} {
get {
if ({Field} == null) {
{Field} = new {Type}();
}
return {Field};
}
}
donde su editor le solicitará el {Tipo}, {Campo}, {Propiedad} específicos, sin tener que volver a escribirlo cada vez.
Si realmente quisieras acortarlo, simplemente eliminaría los corchetes adicionales.
get
{
if (_rows == null)
_rows = new List<Row>();
return _rows;
}
Sugiero operador ternario
get {
return _rows == null ? _rows = new List<Row>() : _rows;
}
O como la
List<Row>
vacía
List<Row>
no
_row
demasiada sobrecarga, ¿por qué no deshacerse del campo
_row
explícito e implementar solo la propiedad de solo lectura (sintaxis
C # 6.0
):
public IList<Row> Rows {get;} = new List<Row>();
Usando el operador de fusión nula (??):
get
{
_rows = _rows ?? new List<Row>();
return _rows;
}
O (menos legible):
get { return _rows ?? (_rows = new List<Row>()); }
Los ?? El operador se llama operador de fusión nula. Devuelve el operando de la izquierda si el operando no es nulo; de lo contrario, devuelve el operando de la derecha.
return _rows ?? (_rows = new List<Row>());
List<Row> _rows;
public List<Row> Rows => _rows ?? (_rows = new List<Row>());