Itu mungkin
tl; dr - Anda dapat mengganti metode get-only dengan setter jika Anda mau. Ini pada dasarnya hanya:
Buat new
properti yang memiliki a get
dan a set
menggunakan nama yang sama.
Jika Anda tidak melakukan hal lain, maka get
metode lama akan tetap dipanggil ketika kelas turunan dipanggil melalui tipe dasarnya. Untuk memperbaikinya, tambahkan abstract
lapisan perantara yang menggunakan metode override
lama get
untuk memaksanya mengembalikan hasil get
metode baru .
Ini memungkinkan kami untuk menimpa properti dengan get
/ set
bahkan jika mereka tidak memiliki satu dalam definisi dasar mereka.
Sebagai bonus, Anda juga dapat mengubah jenis pengembalian jika diinginkan.
Jika definisi dasar adalah get
-hanya, maka Anda dapat menggunakan tipe pengembalian yang lebih diturunkan.
Jika definisi dasar adalah set
-hanya, maka Anda dapat menggunakan tipe pengembalian yang kurang diturunkan.
Jika definisi dasar sudah get
/ set
, maka:
Dalam semua kasus, Anda dapat menyimpan tipe pengembalian yang sama jika Anda mau. Contoh di bawah ini menggunakan tipe pengembalian yang sama untuk kesederhanaan.
Situasi: get
Properti -hanya ada sebelumnya
Anda memiliki beberapa struktur kelas yang tidak dapat Anda modifikasi. Mungkin hanya satu kelas, atau itu pohon warisan yang sudah ada sebelumnya. Apa pun masalahnya, Anda ingin menambahkan set
metode ke properti, tetapi tidak bisa.
public abstract class A // Pre-existing class; can't modify
{
public abstract int X { get; } // You want a setter, but can't add it.
}
public class B : A // Pre-existing class; can't modify
{
public override int X { get { return 0; } }
}
Masalah: Tidak bisa override
dengan get
-hanya dengan get
/set
Anda ingin override
dengan get
/ set
properti, tetapi tidak dapat dikompilasi.
public class C : B
{
private int _x;
public override int X
{
get { return _x; }
set { _x = value; } // Won't compile
}
}
Solusi: Gunakan abstract
lapisan perantara
Meskipun Anda tidak dapat langsung override
dengan get
/ set
properti, Anda dapat :
Buat new
get
/ set
properti dengan nama yang sama.
override
get
metode lama dengan accessor ke get
metode baru untuk memastikan konsistensi.
Jadi, pertama Anda menulis abstract
lapisan perantara:
public abstract class C : B
{
// Seal off the old getter. From now on, its only job
// is to alias the new getter in the base classes.
public sealed override int X { get { return this.XGetter; } }
protected abstract int XGetter { get; }
}
Kemudian, Anda menulis kelas yang tidak akan dikompilasi sebelumnya. Ini akan mengkompilasi kali ini karena Anda tidak benar override
- benar menggunakan get
properti -hanya; alih-alih, Anda menggantinya menggunakan new
kata kunci.
public class D : C
{
private int _x;
public new virtual int X { get { return this._x; } set { this._x = value; } }
// Ensure base classes (A,B,C) use the new get method.
protected sealed override int XGetter { get { return this.X; } }
}
Hasil: Semuanya berfungsi!
Jelas, ini berfungsi seperti yang dimaksudkan untuk D
.
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
test.X = 7;
Print(test.X); // Prints "7", as intended.
Semuanya masih berfungsi sebagaimana dimaksudkan saat melihat D
sebagai salah satu kelas dasar, misalnya A
atau B
. Tapi, alasan mengapa itu bekerja mungkin sedikit kurang jelas.
var test = new D() as B;
//test.X = 7; // This won't compile, because test looks like a B,
// and B still doesn't provide a visible setter.
Namun, definisi kelas dasar get
masih pada akhirnya ditimpa oleh definisi kelas turunan get
, sehingga masih sepenuhnya konsisten.
var test = new D();
Print(test.X); // Prints "0", the default value of an int.
var baseTest = test as A;
Print(test.X); // Prints "7", as intended.
Diskusi
Metode ini memungkinkan Anda untuk menambahkan set
metode ke get
properti -hanya. Anda juga dapat menggunakannya untuk melakukan hal-hal seperti:
Ubah properti apa pun menjadi properti get
-only, set
-only, atau get
-and- set
, terlepas dari apa itu di kelas dasar.
Ubah tipe pengembalian metode dalam kelas turunan.
Kelemahan utama adalah bahwa ada lebih banyak pengkodean untuk dilakukan dan tambahan abstract class
di pohon warisan. Ini bisa sedikit menjengkelkan dengan konstruktor yang mengambil parameter karena harus disalin / ditempelkan di lapisan perantara.