Saya ingin mengatakan:
public void Problem(Guid optional = Guid.Empty)
{
}
Tetapi kompiler mengeluh bahwa Guid.Empty bukan konstanta waktu kompilasi.
Karena saya tidak ingin mengubah API saya tidak bisa menggunakan:
Nullable<Guid>
c#
c#-4.0
optional-parameters
Ian Ringrose
sumber
sumber
Nullable<Guid> optional = null
(atau lebih tepatnya,Guid? optional = null
)? Setiap Panduan yang saat ini diteruskan akan dipaksakan tanpa perubahan kode apa pun yang diperlukan sama sekali.Jawaban:
Larutan
Anda dapat menggunakan
new Guid()
sebagai gantinyaAnda juga bisa menggunakan
default(Guid)
default(Guid)
juga akan bekerja persis sepertinew Guid()
.Karena Guid adalah tipe nilai bukan tipe referensi, jadi,
default(Guid)
tidak sama dengannull
misalnya, sebaliknya, itu sama dengan memanggil konstruktor default.Yang berarti ini:
Persis sama dengan contoh aslinya.
Penjelasan
Kenapa tidak
Guid.Empty
berhasil?Alasan Anda mendapatkan kesalahan adalah karena
Empty
didefinisikan sebagai:Jadi, ini adalah variabel, bukan konstanta (didefinisikan sebagai
static readonly
bukan sebagaiconst
). Compiler hanya dapat memiliki nilai-nilai yang diketahui-compiler sebagai parameter metode nilai-nilai default (tidak-hanya-runtime-dikenal).Akar penyebab adalah bahwa Anda tidak dapat memiliki
const
apapunstruct
satunya, tidak sepertienum
misalnya. Jika Anda mencobanya, itu tidak akan dikompilasi.Alasan sekali lagi adalah itu
struct
bukan tipe primitif.Untuk daftar semua tipe primitif di .NET lihat http://msdn.microsoft.com/en-gb/library/system.typecode.aspx
(catatan yang
enum
biasanya mewarisiint
, yang merupakan primitif)Tapi
new Guid()
tidak konstan juga!Saya tidak mengatakan itu perlu konstan. Perlu sesuatu yang dapat diputuskan dalam waktu kompilasi.
Empty
is a field, jadi, nilainya tidak diketahui dalam waktu kompilasi (hanya pada awal waktu menjalankan).Nilai parameter default harus diketahui pada waktu kompilasi, yang dapat berupa
const
nilai, atau sesuatu yang didefinisikan menggunakan fitur C # yang membuat nilai diketahui pada waktu kompilasi, sepertidefault(Guid)
ataunew Guid()
(yang ditentukan pada waktu kompilasi untukstruct
s karena Anda tidak dapat memodifikasistruct
konstruktor dalam kode).Meskipun Anda dapat memberikan
default
ataunew
dengan mudah, Anda tidak dapat memberikanconst
(karena itu bukan tipe primitif atauenum
seperti yang dijelaskan di atas). Jadi, sekali lagi, tidak mengatakan bahwa parameter opsional itu sendiri membutuhkan nilai konstanta, tetapi diketahui kompiler.sumber
new Guid()
bukan ekspresi konstan, misalnya. C # spec mendefinisikan dengan sangat jelas apa yang diperbolehkan, termasuk tetapi tidak terbatas pada konstanta. (Hanya untuk menjadi jelas, ini secara efektif adalah kompilasi konstanta waktu, hanya saja bukan "ekspresi konstan" dalam istilah spesifikasi C #).default
saat ini :)Guid.Empty
setara dengannew Guid()
, yang setara dengandefault(Guid)
. Jadi Anda bisa menggunakan:atau
Perhatikan bahwa
new Foo()
nilai hanya berlaku ketika:Foo
adalah tipe nilaiDengan kata lain, ketika kompiler tahu itu benar-benar hanya nilai default untuk tipe :)
(Menariknya, saya 99,9% yakin itu tidak akan memanggil
new Foo()
konstruktor kustom apa pun yang mungkin Anda buat. Anda tidak dapat membuat konstruktor semacam itu dalam tipe nilai dalam C #, tetapi Anda dapat melakukannya di IL.)Anda dapat menggunakan
default(Foo)
opsi untuk jenis apa pun .sumber
Nullable<Guid>
, berpotensi.Tidak bisakah kamu menggunakan:
default ( Guid )
?sumber
Operator '??' cannot be applied to operands of type 'System.Guid' and 'System.Guid'
Jawaban yang diterima tidak berfungsi di ASP.NET MVC, dan menyebabkan kesalahan saat ini:
Sebagai gantinya, Anda dapat melakukan hal berikut:
sumber
Kompilernya cukup benar;
Guid.Empty
bukan konstanta waktu kompilasi. Anda dapat mencoba membuat metode kelebihan seperti ini:sumber
Guid x = default(Guid)
sebagai solusinya, ingat bahwa menambahkan fungsi lain yang berlebihan tidak mempersulit API lebih dari menambahkan argumen opsional. Sebenarnya itulah yang dilakukan argumen opsional.