penggabungan nol diterjemahkan secara kasar menjadi return x, unless it is null, in which case return y
Saya sering membutuhkan return null if x is null, otherwise return x.y
Saya bisa menggunakan return x == null ? null : x.y;
Lumayan, tapi yang null
di tengah selalu menggangguku - sepertinya berlebihan. Saya lebih suka sesuatu seperti return x :: x.y;
, di mana yang mengikuti ::
dievaluasi hanya jika yang mendahuluinya tidak null
.
Saya melihat ini sebagai hampir berlawanan ke nol koalesensi, jenis campuran di dengan singkat, inline null-cek, tapi aku [ hampir ] tertentu yang tidak ada operator seperti di C #.
Apakah ada bahasa lain yang memiliki operator seperti itu? Jika ya, apa namanya?
(Saya tahu bahwa saya dapat menulis metode untuk itu di C #; Saya menggunakan return NullOrValue.of(x, () => x.y);
, tetapi jika Anda memiliki sesuatu yang lebih baik, saya ingin melihatnya juga.)
return x ? x.y : NULL
. Hore untuk mengonversi jenis penunjuk ke boolean!Jawaban:
Ada operator dereferencing yang tidak aman (?.) Di Groovy ... Saya pikir itulah yang Anda cari.
(Ini juga disebut operator navigasi yang aman .)
Sebagai contoh:
Ini akan memberikan null jika
person
,person.homeAddress
atauperson.homeAddress.postcode
null.(Ini sekarang tersedia di C # 6.0 tetapi tidak di versi sebelumnya)
sumber
null
, misalnya:def bar = foo ?: "<null>"
Decimal? post = pre == null ? null : SomeMethod( pre );
. Alangkah baiknya jika saya bisa menguranginya menjadi "Decimal? Post = pre :: SomeMethod (pre);"Kami mempertimbangkan untuk menambahkan?. ke C # 4. Itu tidak berhasil; ini adalah fitur "menyenangkan untuk dimiliki", bukan fitur "harus dimiliki". Kami akan mempertimbangkannya lagi untuk versi hipotetis masa depan dari bahasa tersebut, tetapi saya tidak akan menahan napas menunggu jika saya menjadi Anda. Ini tidak mungkin menjadi lebih penting seiring berjalannya waktu. :-)
sumber
Jika Anda memiliki jenis khusus logika boolean hubung singkat, Anda dapat melakukan ini (contoh javascript):
return x && x.y;
Jika
x
nol, maka tidak akan dievaluasix.y
.sumber
Rasanya tepat untuk menambahkan ini sebagai jawaban.
Saya kira alasan mengapa tidak ada hal seperti itu di C # adalah karena, tidak seperti operator penggabungan (yang hanya berlaku untuk jenis referensi), operasi sebaliknya dapat menghasilkan referensi atau jenis nilai (yaitu
class x
dengan anggotaint y
- oleh karena itu sayangnya akan tidak dapat digunakan dalam banyak situasi.Saya tidak mengatakan, bagaimanapun, bahwa saya tidak ingin melihatnya!
Solusi potensial untuk masalah itu akan membuat operator secara otomatis mengangkat ekspresi tipe nilai di sisi kanan ke nullable. Tapi kemudian Anda memiliki masalah bahwa di
x.y
mana y adalah int akan benar-benar kembali danint?
itu akan menyebalkan.Solusi lain, mungkin lebih baik, bagi operator untuk mengembalikan nilai default (yaitu nol atau nol) untuk tipe di sisi kanan jika ekspresi di sebelah kiri adalah nol. Tapi kemudian Anda memiliki masalah membedakan skenario di mana nol / nol sebenarnya dibaca dari
x.y
atau apakah itu disediakan oleh operator akses aman.sumber
int?
sebagai nilai pengembalian default, dan pengguna dapat mengubahnya menjadi int jika dia mau. Misalnya jika saya ingin memanggil beberapa metodeLookup
dengan nilai default -1 jika salah satu referensi saya adalahnull
:foo?.Bar?.Lookup(baz) ?? -1
?. :
menjadi operator terner, di mana sisi kanan harus memiliki tipe yang sama dengan anggota yang sesuai yang diberikan di tengah?Delphi memiliki operator: (bukan.), Yang aman-null.
Mereka berpikir untuk menambahkan?. operator ke C # 4.0 untuk melakukan hal yang sama, tetapi itu mendapat blok pemotongan.
Sementara itu, ada IfNotNull () jenis goresan yang gatal. Ini pasti lebih besar dari?. atau:, tetapi memungkinkan Anda membuat rangkaian operasi yang tidak akan mengganggu NullReferenceException pada Anda jika salah satu anggotanya null.
sumber
?.
adalah fitur bahasa C # 6.0, dan ya itu persis seperti yang diminta OP di sini. Lebih baik terlambat daripada tidak sama sekali ^^Di Haskell, Anda dapat menggunakan
>>
operator:Nothing >> Nothing
adalahNothing
Nothing >> Just 1
adalahNothing
Just 2 >> Nothing
adalahNothing
Just 2 >> Just 1
adalahJust 1
sumber
Haskell punya
fmap
, yang dalam hal ini menurut saya setara denganData.Maybe.map
. Haskell murni berfungsi, jadi apa yang Anda cari adalah yang Anda cariJika
x
adalahNothing
, hasil iniNothing
. Jikax
adalahJust object
, hasil iniJust (select_y object)
. Tidak secantik notasi titik, tetapi mengingat ini adalah bahasa fungsional, gayanya berbeda.sumber
PowerShell memungkinkan Anda mereferensikan properti (tetapi tidak memanggil metode) pada referensi null dan akan mengembalikan null jika instansinya null. Anda dapat melakukan ini di kedalaman apa pun. Saya berharap fitur dinamis C # 4 akan mendukung ini, tetapi ternyata tidak.
$x = $null $result = $x.y # $result is null $x = New-Object PSObject $x | Add-Member NoteProperty y 'test' $result = $x.y # $result is 'test'
Ini tidak bagus tetapi Anda dapat menambahkan metode ekstensi yang akan berfungsi seperti yang Anda gambarkan.
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);
sumber
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; } }
Saya sering membutuhkan logika ini untuk string:
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"
sumber
Buat instance statis kelas Anda di suatu tempat dengan semua nilai default yang tepat untuk anggota.
Sebagai contoh:
z = new Thingy { y=null };
lalu alih-alih file
return x != null ? x.y : null;
kamu bisa menulis
return (x ?? z).y;
sumber
Ini sedang ditambahkan di C # vNext (Roslyn powered C #, rilis dengan Visual Studio 2014).
Ini disebut propagasi Null dan terdaftar di sini sebagai lengkap. https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status
Itu juga tercantum di sini sebagai lengkap: https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c
sumber
Yang disebut "operator bersyarat nol" telah diperkenalkan di C # 6.0 dan Visual Basic 14.
Dalam banyak situasi ini dapat digunakan sebagai kebalikan dari operator penggabungan-nol:
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/language-reference/operators/null-conditional-operators
sumber