Apakah ada cara untuk menggunakan kelas Tuple, tetapi berikan nama-nama item di dalamnya?
Sebagai contoh:
public Tuple<int, int, int int> GetOrderRelatedIds()
Itu mengembalikan id untuk OrderGroupId, OrderTypeId, OrderSubTypeId, dan OrderRequirementId.
Akan menyenangkan untuk memberi tahu pengguna metode saya mana yang mana. (Ketika Anda memanggil metode, hasilnya adalah result.Item1, result.Item2, result.Item3, result.Item4. Tidak jelas mana yang mana.)
(Saya tahu saya hanya bisa membuat kelas untuk menampung semua Id ini, tetapi Id ini sudah memiliki kelas mereka sendiri dan membuat kelas untuk nilai pengembalian metode yang satu ini tampak konyol.)
Tuple
sangat generik, jadi hanya itu yang Anda dapatkanJawaban:
Di C # 7.0 (Visual Studio 2017) ada konstruksi baru untuk melakukan itu:
sumber
List<(int first, int second)>
. Saya harus mengunduh paket System.ValueTuple dari NuGet untuk membuatnya berfungsi di Visual Studio 2017.return (first: first, middle: middle, last: last);
return (first, middle, last);
di .NET 4.7.1 (tidak yakin untuk 4.7.0)ValueTuple
, walaupun biasanya hebat, adalah tipe nilai yang dapat berubah (struct), sementara ituTuple
adalah tipe referensi yang tidak dapat diubah (kelas). Sejauh yang saya tahu, tidak ada cara untuk mendapatkan tipe referensiTuple
dengan nama item yang ramah.Hingga C # 7.0, tidak ada cara untuk melakukan ini dengan mendefinisikan tipe Anda sendiri.
sumber
Ini adalah versi yang terlalu rumit dari apa yang Anda tanyakan:
Mengapa tidak membuat kelas saja?
sumber
Tuple<T, T2>
Anda tidak bisa menjadi struct.Dengan .net 4 Anda mungkin dapat melihat
ExpandoObject
, namun, jangan menggunakannya untuk kasus sederhana ini karena apa yang seharusnya menjadi kesalahan waktu kompilasi menjadi kesalahan run-time.Sesuatu yang layak disebutkan adalah tipe anonim untuk dalam suatu metode , tetapi Anda perlu membuat kelas jika Anda ingin mengembalikannya.
sumber
Mereproduksi jawaban saya dari pos ini karena lebih cocok di sini.
Mulai C # v7.0, sekarang dimungkinkan untuk memberi nama properti tuple yang sebelumnya digunakan sebagai nama standar seperti
Item1
,Item2
dan seterusnya.Memberi nama properti Tuple Literals :
Output pada konsol:
Mengembalikan Tuple (memiliki properti yang diberi nama) dari metode :
Output pada konsol:
Membuat daftar Tuples yang memiliki properti bernama
Output pada konsol:
Saya harap saya sudah membahas semuanya. Dalam hal, ada sesuatu yang saya lewatkan maka tolong beri saya umpan balik dalam komentar.
Catatan : Cuplikan kode saya menggunakan fitur interpolasi string C # v7 seperti yang dijelaskan di sini .
sumber
MichaelMocko Dijawab hebat,
tapi saya ingin menambahkan beberapa hal yang harus saya pahami
Baris di atas akan memberi Anda waktu kompilasi kesalahan jika Anda menggunakan .net framework <4.7
Jadi jika Anda memiliki proyek yang menggunakan .net framework <4.7 dan Anda masih ingin menggunakan ValueTuple daripada workAround akan menginstal paket nuget ini
sumber
Tidak, Anda tidak dapat menyebutkan nama anggota tuple.
Di antara keduanya adalah menggunakan ExpandoObject bukan Tuple.
sumber
Jika jenis barang Anda semuanya berbeda, ini adalah kelas yang saya buat untuk mendapatkannya secara lebih intuitif.
Penggunaan kelas ini:
Kode sumber:
sumber
Ini sangat menjengkelkan dan saya berharap versi C # yang akan datang akan menjawab kebutuhan ini. Saya menemukan pekerjaan yang paling mudah adalah menggunakan tipe struktur data yang berbeda atau mengganti nama "item" untuk kewarasan Anda dan untuk kewarasan orang lain yang membaca kode Anda.
sumber
Saya pikir saya akan membuat kelas tetapi alternatif lain adalah parameter output.
Karena Tuple Anda hanya berisi bilangan bulat, Anda dapat mewakilinya dengan a
Dictionary<string,int>
tapi saya juga tidak merekomendasikan itu.
sumber
Mengapa semua orang membuat hidup begitu sulit. Tuples untuk pemrosesan data yang agak sementara . Bekerja dengan Tuples setiap saat akan membuat kode ini sangat sulit untuk dipahami di beberapa titik. Membuat kelas untuk semuanya pada akhirnya bisa mengasapi proyek Anda.
Ini tentang keseimbangan, namun ...
Masalah Anda tampaknya adalah sesuatu yang Anda inginkan untuk kelas. Dan hanya demi kelengkapan, kelas di bawah ini juga berisi konstruktor.
Ini adalah pola yang tepat untuk
Atau, jika Anda menginginkannya sangat sederhana: Anda juga dapat menggunakan jenis inisialisasi:
sumber
Saya akan menulis nama-nama Item di summay .. jadi dengan melayang di atas fungsi helloworld () teks akan menyapa = Item1 dan world = Item2
sumber
Hanya dengan menambahkan jawaban @MichaelMocko. Tuples punya beberapa gotcha saat ini:
Anda tidak dapat menggunakannya di pohon ekspresi EF
Contoh:
Ini akan gagal dikompilasi dengan "Pohon ekspresi mungkin tidak mengandung kesalahan tuple literal". Sayangnya, pohon ekspresi API tidak diperluas dengan dukungan untuk tupel ketika ini ditambahkan ke bahasa.
Lacak (dan upvote) masalah ini untuk pembaruan: https://github.com/dotnet/roslyn/issues/12897
Untuk mengatasi masalah tersebut, Anda dapat melemparkannya ke jenis anonim terlebih dahulu dan kemudian mengonversi nilainya menjadi tuple:
Opsi lain adalah menggunakan ValueTuple.Create:
Referensi:
https://www.damirscorner.com/blog/posts/20181207-NoSupportForTuplesInExpressionTrees.html
Ubah tipe anonim menjadi tipe tuple C # 7 baru
Anda tidak dapat mendekonstruksi mereka dalam lambda
Ada proposal untuk menambahkan dukungan: https://github.com/dotnet/csharplang/issues/258
Contoh:
Referensi:
Mereka tidak akan membuat serial dengan baik
Nama bidang Tuple hanya tersedia pada waktu kompilasi dan sepenuhnya dihapus pada saat runtime.
Referensi:
sumber
Anda dapat menulis kelas yang berisi Tuple.
Anda perlu mengganti fungsi Equals dan GetHashCode
dan operator == dan! =.
akan kembali:
Benar
Benar
sumber
Contoh tuple C # 7
sumber