Dreaming of things

14Jul/080

const Vs. static readonly

Setelah beberapa yang lalu saya membahas tentang perbedaan antara public variable dan property, kali ini saya akan coba untuk membahas tentang perbedaan antara const dan static readonly.

Jika dilihat dari fungsinya (juga dari namanya), keduanya memiliki fungsi yang sama yaitu; sebagai representasi nilai yang tidak dapat berubah (unchangable value).

Code snippet berikut ini memperlihatkan sebuah class bernama Sepeda yang memiliki sebuah konstan bernama MEREK:

public class Sepeda
{
  public const string MEREK = "Kumbang Tangguh";
  .....................
  .....................
  .....................
}

Nilai sebuah const (baik sebagai field maupun local variable) harus diinisialisasikan langsung di dalam deklarasinya, seperti pada konstan MEREK (sebagai field) di atas yang langsung menginisialisasikan nilai "Kumbang Tangguh" seketika itu juga ketika dideklarasikan.

Ekspresi const field adalah sebuah ekspresi yang dievaluasi ketika compile time. Kita tidak bisa membuat sebuah const field dengan tipe class atau structure. Karena, class dan structure terinisialisasi ketika runtime dengan keyword "new". Reference type yang bisa diasosiasikan pada const hanya string dan null, class dan structure tidak bisa.

Secara implisit, const field adalah sebuah static field. Untuk menggunakan sebuah const field, kita harus memanggilnya dengan fully-qualified class name nya. Katakanlah class Sepeda ini adalah bagian dari sebuah API bernama SepedaAPI yang akan digunakan oleh sebuah aplikasi bernama SepedaUI. Maka, penggunaan konstan MEREK pada aplikasi SepedaUI, akan seperti layaknya penggunaan sebuah static field (dengan menyebutkan fully-qualified class name dari konstan MEREK, yaitu Sepeda):

.....................
.....................
labelMerek.Text = Sepeda.MEREK;
.....................
.....................

Compiler melakukan optimasi referensi terhadap const field. Pada kasus aplikasi SepedaUI ini, property Text dari labelMerek tidak mereferensikan konstan MEREK secara langsung ke assembly SepedaAPI, tetapi konstan MEREK tersebut di-compile menjadi sebuah literal ke dalam assembly SepedaUI itu sendiri. Sehingga, ketika nilai MEREK pada SepedaAPI diubah, misalnya menjadi "Kumbang Loyo", maka setelah SepedaAPI di-compile ulang, perubahan tersebut tidak akan merubah nilai dari labelMerek.Text (kecuali SepedaUI di-compile ulang juga). Karena, ketika pertama kali SepedaUI di-compile, labelMerek.Text tidak mereferensikan nilainya pada assembly SepedaAPI, akan tetapi compiler meng-compile langsung const MEREK menjadi string literal "Kumbang Tangguh" ke dalam executable SepedaUI. Terang saja perubahan apapun yang terjadi pada const MEREK tidak akan merubah nilai labelMerek.Text kecuali aplikasi SepedaUI ikut di-compile ulang juga. Seperti itulah Compiler melakukan optimasi referensi terhadap const field.

Berbeda dengan const, selain modifier readonly hanya dapat digunakan pada field (tidak bisa pada local variable), nilai dari sebuah readonly field bisa diinisialisasikan ketika deklarasi (sama halnya dengan const field) atau di dalam constructor sebuah class, seperti pada contoh berikut:

public class Mobil
{
  public readonly string MEREK;

  public Mobil()
  {
    MEREK = "Mak Wuuuusss";
  }

  public Mobil(string merek)
  {
    MEREK = merek;
  }
}

Karena ekspresi nya dievaluasi ketika runtime, tipe dari sebuah readonly field bisa diasosiasikan dengan class atau structure.

readonly field bisa digunakan sebagai instance field (terlihat pada contoh class Mobil di atas), atau sebagai static field (dengan menambahkan modifier static).

Salah satu hal yang menarik dari readonly field, kita bisa membuat runtime constant dengan menggunakan readonly field:

public static readonly DateTime CURRENT = DateTime.Now;

Kembali pada masalah SepedaAPI dan SepedaUI, kita bisa mengganti const MEREK dengan readonly. Tentu saja kita harus membuatnya sebagai static field, karena const itu sendiri adalah sebuah static field.

public class Sepeda
{
  public static readonly string MEREK = "Kumbang Tangguh";
  .....................
  .....................
  .....................
}

Keuntungan yang kita dapatkan dengan mengganti const MEREK menjadi static readonly adalah; labelMerek.Text pada assembly SepedaUI akan mereferensikan nilainya secara langsung pada SepedaAPI. Sehingga, perubahan apapun yang terjadi pada MEREK, akan ikut merubah nilai dari labelMerek.Text tanpa perlu melakukan compile ulang executable SepedaUI. Karena ketika SepedaUI di-compile pertama kali, konstan MEREK tidak di-compile menjadi literal ke dalam executable SepedaUI, melainkan direferensikan secara langsung pada konstan MEREK dari SepedaAPI.

Dari sini kita bisa melihat, selain perbedaan antara const dan readonly itu sendiri tentunya, penggunaan static readonly lebih direkomendasikan daripada const. Lalu kapankah kita menggunakan const? Ketika kita benar-benar yakin bahwa nilai yang dibawa oleh const field tersebut adalah sebuah nilai yang tidak akan pernah berubah, misalnya nilai PI dari sebuah lingkaran.

Sedikit tambahan, jika kita lihat isi assembly yang kita buat dengan menggunakan tool ILDASM (Intermediate Language Disassembler), maka jika kita menggunakan const field untuk konstan MEREK, akan terlihat seperti ini:

.field public static literal string MEREK = "Kumbang Tangguh"

Sementara, jika kita menggunakan static readonly, akan terlihat seperti ini:

.field public static initonly string MEREK

Semoga bermanfaat ^^