Pertanyaan "Const correctness" dalam C #


Inti dari kebenaran-const adalah untuk dapat memberikan pandangan dari sebuah contoh yang tidak dapat diubah atau dihapus oleh pengguna. Compiler mendukung ini dengan menunjukkan ketika Anda memecahkan konstanta dari dalam fungsi const, atau mencoba menggunakan fungsi non-const dari objek const. Jadi tanpa menyalin pendekatan const, apakah ada metodologi yang dapat saya gunakan dalam C # yang memiliki tujuan yang sama?

Saya menyadari kekekalan, tetapi itu tidak benar-benar terbawa ke benda-benda peti kemas untuk nama tetapi satu contoh.


75
2017-09-22 10:25


asal


Jawaban:


Saya telah menemukan masalah ini berkali-kali dan akhirnya menggunakan antarmuka.

Saya pikir penting untuk membuang gagasan bahwa C # adalah bentuk apa pun, atau bahkan evolusi C ++. Mereka adalah dua bahasa berbeda yang berbagi sintaks yang hampir sama.

Saya biasanya menyatakan 'const correctness' dalam C # dengan mendefinisikan tampilan read-only dari suatu kelas:

public interface IReadOnlyCustomer
{
    String Name { get; }
    int Age { get; }
}

public class Customer : IReadOnlyCustomer
{
    private string m_name;
    private int m_age;

    public string Name
    {
        get { return m_name; }
        set { m_name = value; }
    }

    public int Age
    {
        get { return m_age; }
        set { m_age = value; }
    }
}

59
2017-09-22 13:19



Untuk mendapatkan manfaat dari const-craziness (atau kemurnian dalam istilah pemrograman fungsional), Anda perlu merancang kelas Anda dengan cara sehingga mereka tidak berubah, sama seperti kelas String c # adalah.

Pendekatan ini jauh lebih baik daripada hanya menandai objek sebagai hanya baca, karena dengan kelas yang tidak dapat diubah, Anda dapat mengirim data dengan mudah di lingkungan multi-tasking.


28
2017-09-22 10:45



Saya hanya ingin mencatat untuk Anda bahwa banyak dari System.Collections.Generics kontainer memiliki metode AsReadOnly yang akan memberi Anda kembali koleksi abadi.


23
2017-09-23 13:40



C # tidak memiliki fitur seperti itu. Anda dapat memberikan argumen berdasarkan nilai atau dengan referensi. Referensi itu sendiri tidak berubah kecuali Anda menentukan ref pengubah. Tetapi data yang direferensikan tidak berubah. Jadi Anda perlu berhati-hati jika ingin menghindari efek samping.

MSDN:

Passing Parameters


4
2017-09-22 10:30



Antarmuka adalah jawabannya, dan sebenarnya lebih kuat daripada "const" dalam C ++. const adalah solusi satu-ukuran-untuk-semua untuk masalah di mana "const" didefinisikan sebagai "tidak menetapkan anggota atau memanggil sesuatu yang menetapkan anggota". Itu singkatan yang baik untuk const-ness dalam banyak skenario, tetapi tidak semuanya. Sebagai contoh, pertimbangkan fungsi yang menghitung nilai berdasarkan beberapa anggota tetapi juga cache hasil. Dalam C ++, itu dianggap non-const, meskipun dari perspektif pengguna itu pada dasarnya adalah const.

Antarmuka memberi Anda lebih banyak fleksibilitas dalam menentukan bagian spesifik dari kemampuan yang ingin Anda sediakan dari kelas Anda. Ingin const-ness? Hanya menyediakan antarmuka tanpa metode bermutasi. Ingin memperbolehkan pengaturan beberapa hal tetapi tidak yang lain? Berikan antarmuka hanya dengan metode tersebut.


3
2017-09-22 17:33



Setuju dengan beberapa orang lain melihat menggunakan bidang hanya baca yang Anda inisialisasi dalam konstruktor, untuk membuat objek yang tidak dapat diubah.

    public class Customer
    {
    private readonly string m_name;
    private readonly int m_age;

    public Customer(string name, int age)
    {
        m_name = name;
        m_age = age;
    }

    public string Name
    {
        get { return m_name; }
    }

    public int Age
    {
        get { return m_age; }
    }
  }

Atau Anda juga dapat menambahkan cakupan akses pada properti, yaitu get publik dan kumpulan dilindungi?

    public class Customer
    {
    private string m_name;
    private int m_age;

    protected Customer() 
    {}

    public Customer(string name, int age)
    {
        m_name = name;
        m_age = age;
    }

    public string Name
    {
        get { return m_name; }
        protected set { m_name = value; }
    }

    public int Age
    {
        get { return m_age; }
        protected set { m_age = value; }
    }
  }

3
2017-09-25 11:26



  • Itu const kata kunci dapat digunakan untuk mengkompilasi konstanta waktu seperti tipe dan string primitif
  • Itu hanya bisa dibaca kata kunci dapat digunakan untuk konstanta run-time seperti tipe referensi

Masalah dengan hanya bisa dibacaadalah bahwa itu hanya memungkinkan referensi (pointer) menjadi konstan. Hal yang direferensikan (menunjuk ke) masih bisa dimodifikasi. Ini adalah bagian yang sulit tetapi tidak ada jalan lain. Untuk menerapkan objek konstan berarti membuat mereka tidak mengekspos metode atau properti yang bisa berubah tetapi ini aneh.

Lihat juga Efektif C #: 50 Cara Khusus untuk Meningkatkan C # Anda (Butir 2 - Lebih suka baca ke const.)


2
2017-09-22 12:32