Dimulai dengan C # 8.0 pada .NET Core 3.0, saat membuat anggota antarmuka, Anda dapat menentukan implementasinya. Skenario yang paling umum adalah menambahkan anggota secara aman ke antarmuka yang sudah dirilis dan digunakan oleh banyak klien.
Dalam panduan ini Anda akan belajar cara:
- Aman untuk memperluas antarmuka dengan menambahkan metode dengan implementasi.
- Buat implementasi parameter untuk fleksibilitas yang lebih besar.
- Dapatkan hak untuk mengimplementasikan implementasi yang lebih spesifik dengan kemungkinan kontrol manual.

Di mana untuk memulai?
Pertama, Anda perlu mengkonfigurasi mesin untuk bekerja dengan .NET Core, termasuk kompiler dari pratinjau C # 8.0. Kompiler semacam itu tersedia mulai dengan Visual Studio 2019 , atau dengan SDK pratinjau .NET Core 3.0 yang lebih baru. Anggota antarmuka default tersedia mulai dengan .NET Core 3.0 (Pratinjau 4).
Ikhtisar skenario
Tutorial ini dimulai dengan versi pertama dari perpustakaan hubungan pelanggan. Anda bisa mendapatkan aplikasi starter di repositori kami di GitHub . Perusahaan yang membuat perpustakaan ini berasumsi bahwa pelanggan dengan aplikasi yang ada akan menyesuaikannya dengan perpustakaan ini. Para pengguna diberikan definisi antarmuka minimum untuk implementasi:
public interface ICustomer { IEnumerable<IOrder> PreviousOrders { get; } DateTime DateJoined { get; } DateTime? LastOrder { get; } string Name { get; } IDictionary<DateTime, string> Reminders { get; } }
Antarmuka kedua juga ditentukan yang menunjukkan urutan:
public interface IOrder { DateTime Purchased { get; } decimal Cost { get; } }
Berdasarkan antarmuka ini, tim dapat membangun perpustakaan untuk penggunanya untuk menciptakan pengalaman terbaik bagi pelanggan. Tujuan tim adalah untuk meningkatkan tingkat interaksi dengan pelanggan yang sudah ada dan mengembangkan hubungan dengan yang baru.
Saatnya memperbarui perpustakaan untuk rilis berikutnya. Salah satu fitur yang paling populer adalah penambahan diskon untuk pelanggan setia yang melakukan banyak pesanan. Diskon individual baru ini diterapkan setiap kali pelanggan melakukan pemesanan. Dengan setiap implementasi ICustomer, aturan yang berbeda dapat ditetapkan untuk diskon untuk loyalitas.
Cara paling mudah untuk menambahkan fitur ini adalah memperluas antarmuka ICustomer
dengan diskon apa pun. Proposal ini telah menimbulkan kekhawatiran di antara pengembang yang berpengalaman. βAntarmuka tidak berubah setelah rilis! Ini adalah perubahan kritis! " Di C # 8.0, implementasi antarmuka default untuk memperbarui antarmuka telah ditambahkan. Penulis perpustakaan dapat menambahkan anggota baru dan menerapkannya secara default
Implementasi default dari antarmuka memungkinkan pengembang untuk memperbarui antarmuka, sementara masih memungkinkan pengembang lain untuk menimpa implementasi ini. Pengguna perpustakaan dapat menerima implementasi default sebagai perubahan yang tidak kritis.
Perbarui menggunakan anggota antarmuka default
Tim setuju dengan implementasi standar yang paling mungkin: diskon pada loyalitas pelanggan.
Pembaruan harus berfungsi untuk menetapkan dua properti: jumlah pesanan yang diperlukan untuk menerima diskon, dan persentase diskon. Ini membuatnya menjadi skrip yang ideal untuk anggota antarmuka default. Anda dapat menambahkan metode ke antarmuka ICustomer dan memberikan implementasinya yang paling mungkin. Semua implementasi yang ada dan yang baru dapat diimplementasikan secara default atau memiliki pengaturan sendiri.
Pertama-tama tambahkan metode baru ke implementasi:
Penulis perpustakaan menulis tes pertama untuk memverifikasi implementasi:
SampleCustomer c = new SampleCustomer("customer one", new DateTime(2010, 5, 31)) { Reminders = { { new DateTime(2010, 08, 12), "childs's birthday" }, { new DateTime(1012, 11, 15), "anniversary" } } }; SampleOrder o = new SampleOrder(new DateTime(2012, 6, 1), 5m); c.AddOrder(o); o = new SampleOrder(new DateTime(2103, 7, 4), 25m); c.AddOrder(o);
Perhatikan bagian tes berikut:
Bagian ini, dari ICustomer
ke ICustomer
adalah penting. Kelas SampleCustomer
tidak SampleCustomer
menyediakan implementasi untuk ComputeLoyaltyDiscount
; ini disediakan oleh antarmuka ICustomer
. Namun, kelas SampleCustomer
tidak mewarisi anggota dari interface-nya. Aturan ini belum berubah. Untuk memanggil metode apa pun yang diterapkan dalam suatu antarmuka, variabel tersebut harus berupa tipe antarmuka, dalam contoh ini ICustomer
.
Parameterisasi
Ini awal yang bagus. Tetapi implementasi standar terlalu terbatas. Banyak konsumen dari sistem ini dapat memilih ambang yang berbeda untuk jumlah pembelian, durasi keanggotaan yang berbeda atau diskon dalam persen yang berbeda. Anda dapat meningkatkan proses peningkatan untuk lebih banyak pelanggan dengan menyediakan cara untuk mengatur parameter ini. Mari kita tambahkan metode statis yang menetapkan tiga parameter ini yang mengontrol implementasi default:
Sepotong kode kecil ini menunjukkan banyak fitur bahasa baru. Antarmuka sekarang dapat menyertakan anggota statis, termasuk bidang dan metode. Berbagai pengubah akses juga disertakan. Bidang tambahan bersifat pribadi, dan metode baru bersifat publik. Setiap pengubah diizinkan untuk anggota antarmuka.
Aplikasi yang menggunakan rumus umum untuk menghitung diskon loyalitas, tetapi dengan parameter yang berbeda, seharusnya tidak menyediakan implementasi kustom; mereka dapat mengatur argumen dengan metode statis. Misalnya, kode berikut mengatur "apresiasi pelanggan," yang memberikan imbalan kepada pelanggan mana pun dengan keanggotaan lebih dari satu bulan:
ICustomer.SetLoyaltyThresholds(new TimeSpan(30, 0, 0, 0), 1, 0.25m); Console.WriteLine($"Current discount: {theCustomer.ComputeLoyaltyDiscount()}");
Perpanjang implementasi standar
Kode yang Anda tambahkan sebelumnya memberikan implementasi yang nyaman untuk skenario di mana pengguna menginginkan sesuatu seperti implementasi default atau memberikan seperangkat aturan yang tidak terkait. Untuk versi final, mari kita mengatur ulang kode sedikit untuk memasukkan skenario di mana pengguna mungkin ingin bergantung pada implementasi default.
Pertimbangkan startup yang ingin menarik pelanggan baru. Mereka menawarkan diskon 50% untuk pesanan pertama pelanggan baru. Pelanggan yang ada menerima diskon standar. Penulis perpustakaan perlu memindahkan implementasi default ke metode protected static
sehingga setiap kelas yang mengimplementasikan antarmuka ini dapat menggunakan kembali kode dalam implementasinya. Implementasi default dari anggota antarmuka juga memanggil metode umum ini:
public decimal ComputeLoyaltyDiscount() => DefaultLoyaltyDiscount(this); protected static decimal DefaultLoyaltyDiscount(ICustomer c) { DateTime start = DateTime.Now - length; if ((c.DateJoined < start) && (c.PreviousOrders.Count() > orderCount)) { return discountPercent; } return 0; }
Dalam implementasi kelas yang mengimplementasikan antarmuka ini, Anda dapat secara manual memanggil metode pembantu statis dan memperluas logika ini untuk memberikan diskon kepada "klien baru":
public decimal ComputeLoyaltyDiscount() { if (PreviousOrders.Any() == false) return 0.50m; else return ICustomer.DefaultLoyaltyDiscount(this); }
Anda dapat melihat semua kode yang sudah selesai di repositori kami di GitHub .
Fitur-fitur baru ini berarti bahwa antarmuka dapat diperbarui dengan aman jika ada implementasi standar yang dapat diterima untuk anggota baru. Desain antarmuka dengan hati-hati untuk mengekspresikan ide-ide fungsional individual yang dapat diimplementasikan oleh beberapa kelas. Ini membuatnya mudah untuk memperbarui definisi antarmuka ini ketika persyaratan baru ditemukan untuk ide fungsional yang sama.