Domanda

nulla a coalescenza traduce approssimativamente return x, unless it is null, in which case return y

ho spesso bisogno return null if x is null, otherwise return x.y

posso usare return x == null ? null : x.y;

Non male, ma che null nel mezzo sempre mi dà fastidio - sembra superfluo. Preferirei qualcosa di simile return x :: x.y;, dove ciò che segue il :: solo viene valutato se ciò che lo precede non è null.

Io vedo questo come quasi un opposto null coalescenza, sorta di misto con un laconico, in linea null-controllo, ma io sono [ quasi ] certo che non c'è tale operatore in C #.

Ci sono altre lingue che hanno un tale operatore? Se è così, come si chiama?

(so che posso scrivere un metodo per esso in C #;. Io uso return NullOrValue.of(x, () => x.y);, ma se avete qualcosa di meglio, mi piacerebbe vedere che troppo)

È stato utile?

Soluzione

C'è il nullo-safe operatore dereferenziazione (?.) In Groovy ... Penso che sia quello che stai dopo.

(E 'anche chiamata la navigazione sicura dell'operatore . )

Ad esempio:

homePostcode = person?.homeAddress?.postcode

Questo darà null se person, person.homeAddress o person.homeAddress.postcode è nullo.

(Questo è ora disponibili in C # 6.0 ma non in precedenza le versioni)

Altri suggerimenti

Abbiamo preso in considerazione l'aggiunta di?. a C # 4. Non aveva il taglio; si tratta di un "bello avere" caratteristica, non un "Gotta have" caratteristica. Noi prenderemo in considerazione di nuovo per le versioni future ipotetiche del linguaggio, ma non mi trattengo il respiro in attesa, se fossi in te. Non è probabile che per ottenere più importante col passare del tempo. : -)

Se hai un particolare tipo di corto circuito logica booleana, si può fare questo (ad esempio javascript):

return x && x.y;

Se x è nullo, allora non valutare x.y.

Mi sembrava giusto per aggiungere questo come una risposta.

Credo che la ragione per la quale non v'è nulla di simile in C # è perché, a differenza l'operatore coalescenza (che è valido solo per i tipi di riferimento), l'operazione inversa potrebbe produrre sia un tipo di riferimento o di valore (cioè class x con gli int y - quindi sarebbe purtroppo inutilizzabile in molte situazioni.

Non sto dicendo, però, che non mi piacerebbe vederlo!

Una possibile soluzione a questo problema sarebbe per l'operatore solleva automaticamente un tipo di valore espressione a destra-lato ad una annullabile. Ma allora si ha il problema che x.y dove y è un int effettivamente restituito un int? che sarebbe un dolore.

Un altro, probabilmente migliore soluzione sarebbe per l'operatore per restituire il valore predefinito (cioè null o zero) per il tipo sul lato destro se l'espressione a sinistra è nullo. Ma poi avete problemi che contraddistinguono scenari in cui un / null zero è stato effettivamente letto da x.y o se sia stata fornita dall'operatore di sicurezza di accesso.

Delphi ha:. (. Anziché) operatore, che è nullo-safe

che stavano pensando di aggiungere una?. all'operatore di C # 4.0 per fare lo stesso, ma che ha ottenuto il blocco di modulazione.

Nel frattempo, c'è IfNotNull () quale tipo di graffi che prurito. E 'certamente più grande di?. o:., ma non consentono di comporre una catena di operazioni che non Hork un NullReferenceException a voi se uno dei membri è null

In Haskell, è possibile utilizzare l'operatore >>:

  • Nothing >> Nothing IS Nothing
  • Nothing >> Just 1 IS Nothing
  • Just 2 >> Nothing IS Nothing
  • Just 2 >> Just 1 IS Just 1

Haskell ha fmap, che in questo caso credo sia toData.Maybe.map equivalente. Haskell è puramente funzionale, così che cosa state cercando sarebbe

fmap select_y x

Se x è Nothing, restituisce Nothing. Se x è Just object, restituisce Just (select_y object). Non bella come notazione del punto, ma dato che si tratta di un linguaggio funzionale, gli stili sono diversi.

PowerShell vi lasciate riferimento proprietà (ma non i metodi di chiamata) su un riferimento null e restituirà null se l'istanza è null. Lo si può fare a qualsiasi profondità. Avevo sperato che C # caratteristica dinamica di 4 sosterrebbe questo, ma non è così.

$x = $null
$result = $x.y  # $result is null

$x = New-Object PSObject
$x | Add-Member NoteProperty y 'test'
$result = $x.y  # $result is 'test'

Non è bello, ma si potrebbe aggiungere un metodo di estensione che funzionerà il modo in cui si descrive.

public static TResult SafeGet<T, TResult>(this T obj, Func<T, TResult> selector) {
    if (obj == null) { return default(TResult); }
    else { return selector(obj); }
}

var myClass = new MyClass();
var result = myClass.SafeGet(x=>x.SomeProp);
public class ok<T> {
    T s;
    public static implicit operator ok<T>(T s) { return new ok<T> { s = s }; }
    public static implicit operator T(ok<T> _) { return _.s; }

    public static bool operator true(ok<T> _) { return _.s != null; }
    public static bool operator false(ok<T> _) { return _.s == null; }
    public static ok<T> operator &(ok<T> x, ok<T> y) { return y; }
}

ho spesso bisogno questa logica per le stringhe:

using ok = ok<string>;

...

string bob = null;
string joe = "joe";

string name = (ok)bob && bob.ToUpper();   // name == null, no error thrown
string boss = (ok)joe && joe.ToUpper();   // boss == "JOE"

Creare un'istanza statica del vostro posto di classe con tutti i valori di default giusti per i membri.

Ad esempio:

z = new Thingy { y=null };

allora al posto del tuo

return x != null ? x.y : null;

è possibile scrivere

return (x ?? z).y;

Questo è stato aggiunto in C # vNext (Roslyn alimentato C #, uscite con Visual Studio 2014).

Si chiama Null propagazione ed è elencato qui come completa. https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status

E 'anche elencati qui il più completo: https://visualstudio.uservoice.com / forum / 121579-visual-studio / suggerimenti / 3.990.187-add-operatore-to-c

Il cosiddetto "operatore null-condizionale" è stato introdotto in C # 6.0 e in Visual Basic 14.
In molte situazioni può essere utilizzato come l'esatto opposto dell'operatore null coalescenza:

int? length = customers?.Length; // null if customers is null   
Customer first = customers?[0];  // null if customers is null  
int? count = customers?[0]?.Orders?.Count();  // null if customers, the first customer, or Orders is null

https: // docs .microsoft.com / en-us / dotnet / csharp / lingua-reference / operatori / null-condizionali-operatori

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top