Itu mungkin
tl; dr - Anda dapat mengganti metode get-only dengan setter jika Anda mau. Ini pada dasarnya hanya:
Buat newproperti yang memiliki a getdan a setmenggunakan nama yang sama.
Jika Anda tidak melakukan hal lain, maka getmetode lama akan tetap dipanggil ketika kelas turunan dipanggil melalui tipe dasarnya. Untuk memperbaikinya, tambahkan abstractlapisan perantara yang menggunakan metode overridelama getuntuk memaksanya mengembalikan hasil getmetode baru .
Ini memungkinkan kami untuk menimpa properti dengan get/ setbahkan 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: getProperti -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 setmetode 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 overridedengan get-hanya dengan get/set
Anda ingin overridedengan get/ setproperti, 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 abstractlapisan perantara
Meskipun Anda tidak dapat langsung overridedengan get/ setproperti, Anda dapat :
Buat new get/ setproperti dengan nama yang sama.
overridegetmetode lama dengan accessor ke getmetode baru untuk memastikan konsistensi.
Jadi, pertama Anda menulis abstractlapisan 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 getproperti -hanya; alih-alih, Anda menggantinya menggunakan newkata 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 Dsebagai salah satu kelas dasar, misalnya Aatau 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 getmasih 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 setmetode ke getproperti -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 classdi pohon warisan. Ini bisa sedikit menjengkelkan dengan konstruktor yang mengambil parameter karena harus disalin / ditempelkan di lapisan perantara.