Share via


Sistem jenis umum

Sistem jenis umum menentukan bagaimana jenis dideklarasikan, digunakan, dan dikelola dalam runtime bahasa umum, dan juga merupakan bagian penting dari dukungan runtime untuk integrasi lintas bahasa. Sistem jenis umum melakukan fungsi berikut:

  • Menetapkan kerangka kerja yang membantu mengaktifkan integrasi lintas bahasa, keamanan jenis, dan eksekusi kode berkinerja tinggi.

  • Menyediakan model berorientasi objek yang mendukung implementasi lengkap dari banyak bahasa pemrograman.

  • Menentukan aturan yang harus diikuti bahasa, yang membantu memastikan bahwa objek yang ditulis dalam bahasa yang berbeda dapat berinteraksi satu sama lain.

  • Menyediakan pustaka yang berisi jenis data primitif (seperti Boolean, Byte, Char, Int32, dan UInt64) yang digunakan dalam pengembangan aplikasi.

Jenis dalam .NET

Semua jenis dalam .NET adalah jenis nilai atau jenis referensi.

Jenis nilai adalah jenis data yang objeknya diwakili oleh nilai aktual objek. Jika instans jenis nilai ditetapkan ke variabel, variabel tersebut diberi salinan nilai baru.

Jenis referensi adalah jenis data yang direpresentasikan oleh referensi (serupa dengan penunjuk) ke nilai aktual objek. Jika jenis referensi ditetapkan ke variabel, variabel tersebut mereferensikan (menunjuk ke) nilai asli. Tidak ada salinan yang dibuat.

Sistem jenis umum di .NET mendukung lima kategori jenis berikut:

Kelas

Kelas adalah jenis referensi yang dapat diturunkan langsung dari kelas lain dan yang berasal secara implisit dari System.Object. Kelas menentukan operasi yang objek (yang merupakan instans kelas) dapat lakukan (metode, peristiwa, atau properti) dan data yang dikandung objek (bidang). Meskipun kelas umumnya mencakup definisi dan implementasi (tidak seperti antarmuka, misalnya, yang hanya berisi definisi tanpa implementasi), kelas dapat memiliki satu atau beberapa anggota yang tidak memiliki implementasi.

Tabel berikut ini menjelaskan beberapa karakteristik yang mungkin dimiliki kelas. Setiap bahasa yang mendukung runtime menyediakan cara untuk menunjukkan bahwa kelas atau anggota kelas memiliki satu atau beberapa karakteristik ini. Namun, bahasa pemrograman individual yang menargetkan .NET mungkin tidak membuat semua karakteristik ini tersedia.

Karakteristik Deskripsi
disegel Menentukan bahwa kelas lain tidak dapat berasal dari tipe ini.
implements Menunjukkan bahwa kelas menggunakan satu atau beberapa antarmuka dengan menyediakan implementasi anggota antarmuka.
abstrak Menunjukkan bahwa kelas tidak dapat diinstansiasi. Untuk menggunakannya, Anda harus mendapatkan kelas lain darinya.
mewarisi Menunjukkan bahwa instans kelas dapat digunakan di mana saja kelas dasar ditentukan. Kelas turunan yang mewarisi dari kelas dasar dapat menggunakan implementasi anggota publik apa pun yang disediakan oleh kelas dasar, atau kelas turunan dapat menggantikan implementasi anggota publik dengan implementasinya sendiri.
diekspor atau tidak diekspor Menunjukkan apakah kelas terlihat di luar rakitan tempat kelas didefinisikan. Karakteristik ini hanya berlaku untuk kelas tingkat atas dan bukan untuk kelas berlapis.

Catatan

Kelas juga dapat ditumpuk di kelas atau struktur induk. Kelas berlapis juga memiliki karakteristik anggota. Untuk informasi selengkapnya, lihat Jenis Berlapis.

Anggota kelas yang tidak memiliki implementasi adalah anggota abstrak. Kelas yang memiliki satu atau beberapa anggota abstrak itu sendiri abstrak; instans baru tidak dapat dibuat. Beberapa bahasa yang menargetkan runtime memungkinkan Anda menandai kelas sebagai abstrak meskipun tidak ada anggotanya yang abstrak. Anda dapat menggunakan kelas abstrak saat ingin merangkum serangkaian fungsionalitas dasar yang dapat mewarisi atau mengambil alih kelas jika sesuai. Kelas yang tidak abstrak disebut sebagai kelas konkret.

Kelas dapat mengimplementasikan sejumlah antarmuka, tetapi hanya dapat mewarisi dari satu kelas dasar selain System.Object, dari mana semua kelas mewarisi secara implisit. Semua kelas harus memiliki setidaknya satu konstruktor, yang menginisialisasi instans baru kelas. Jika Anda tidak secara eksplisit mendefinisikan konstruktor, sebagian besar kompilator akan secara otomatis memberikan konstruktor tanpa parameter.

Struktur

Struktur adalah jenis nilai yang berasal secara implisit dari System.ValueType, yang pada gilirannya berasal dari System.Object. Struktur berguna untuk mewakili nilai yang persyaratan memorinya kecil, dan untuk meneruskan nilai sebagai parameter berdasarkan nilai ke metode yang memiliki parameter yang diketik dengan kuat. Dalam .NET, semua jenis data primitif (Boolean, Byte, Char, DateTime, Decimal, Double, Int16, Int32, Int64, SByte, Single, UInt16, UInt32, dan UInt64) didefinisikan sebagai struktur.

Seperti kelas, struktur menentukan data (bidang struktur) dan operasi yang dapat dilakukan pada data tersebut (metode struktur). Ini berarti Anda dapat memanggil metode pada struktur, termasuk metode virtual yang ditentukan pada System.Object kelas dan System.ValueType, dan metode apa pun yang ditentukan pada jenis nilai itu sendiri. Dengan kata lain, struktur dapat memiliki bidang, properti, dan peristiwa, serta metode statis dan nonstatis. Anda dapat membuat instans struktur, meneruskannya sebagai parameter, menyimpannya sebagai variabel lokal, atau menyimpannya di bidang jenis nilai atau jenis referensi lain. Struktur juga dapat mengimplementasikan antarmuka.

Jenis nilai juga berbeda dari kelas dalam beberapa hal. Pertama, meskipun mereka secara implisit mewarisi dari System.ValueType, mereka tidak dapat langsung mewarisi dari jenis apa pun. Demikian pula, semua jenis nilai disegel, yang berarti bahwa tidak ada jenis lain yang dapat berasal darinya. Mereka juga tidak memerlukan konstruktor.

Untuk setiap jenis nilai, runtime bahasa umum menyediakan jenis kotak yang sesuai, yang merupakan kelas yang memiliki status dan perilaku yang sama dengan jenis nilai. Instans jenis nilai dikotak ketika diteruskan ke metode yang menerima parameter jenis System.Object. Ini tidak dikotak (yaitu, dikonversi dari instans kelas kembali ke instans jenis nilai) saat kontrol kembali dari panggilan metode yang menerima jenis nilai sebagai parameter referensi. Beberapa bahasa mengharuskan Anda menggunakan sintaks khusus saat jenis kotak diperlukan; yang lain secara otomatis menggunakan jenis kotak ketika diperlukan. Saat Anda menentukan jenis nilai, Anda menentukan jenis kotak dan yang tidak dikotak.

Enumerasi

Enumerasi adalah jenis nilai yang mewarisi langsung dari System.Enum dan yang memasok nama alternatif untuk nilai jenis primitif yang mendasar. Jenis enumerasi memiliki nama, jenis yang mendasar yang harus menjadi salah satu jenis bilangan bulat bawaan yang ditandatangani atau tidak ditandatangani (seperti Byte, Int32, atau UInt64), dan sekumpulan bidang. Bidang adalah bidang harfiah statik, yang masing-masing mewakili konstanta. Nilai yang sama dapat ditetapkan ke beberapa bidang. Ketika ini terjadi, Anda harus menandai salah satu nilai sebagai nilai enumerasi utama untuk refleksi dan konversi string.

Anda dapat menetapkan nilai jenis yang mendasarinya ke enumerasi dan sebaliknya (tidak ada transmisi yang diperlukan oleh runtime). Anda dapat membuat instans enumerasi dan memanggil metode System.Enum, serta metode apa pun yang ditentukan pada jenis enumerasi yang mendasar. Namun, beberapa bahasa mungkin tidak memungkinkan Anda meneruskan enumerasi sebagai parameter ketika instans jenis yang mendasar diperlukan (atau sebaliknya).

Pembatasan tambahan berikut berlaku untuk enumerasi:

  • Mereka tidak dapat mendefinisikan metode mereka sendiri.

  • Mereka tidak dapat mengimplementasikan antarmuka.

  • Mereka tidak dapat menentukan properti atau peristiwa.

  • Mereka tidak bisa generik, kecuali mereka generik hanya karena mereka bersarang dalam jenis generik. Artinya, enumerasi tidak dapat memiliki parameter jenis sendiri.

    Catatan

    Jenis berlapis (termasuk enumerasi) yang dibuat dengan Visual Basic, C#, dan C++ menyertakan parameter jenis dari semua jenis generik yang mengapit, dan oleh karena itu umum meskipun mereka tidak memiliki parameter jenisnya sendiri. Untuk informasi selengkapnya, lihat "Jenis Berlapis" dalam Type.MakeGenericType topik referensi.

Atribut FlagsAttribute menunjukkan jenis enumerasi khusus yang disebut bidang bit. Runtime itu sendiri tidak membedakan antara enumerasi tradisional dan bidang bit, tetapi bahasa Anda mungkin melakukannya. Ketika perbedaan ini dibuat, operator bitwise dapat digunakan pada bidang bit, tetapi tidak pada enumerasi, untuk menghasilkan nilai yang tidak disebutkan namanya. Enumerasi umumnya digunakan untuk daftar elemen unik, seperti hari dalam seminggu, nama negara atau wilayah, dan sebagainya. Bidang bit umumnya digunakan untuk daftar kualitas atau jumlah yang mungkin terjadi dalam kombinasi, seperti Red And Big And Fast.

Contoh berikut menunjukkan cara menggunakan bidang bit dan enumerasi tradisional.

using System;
using System.Collections.Generic;

// A traditional enumeration of some root vegetables.
public enum SomeRootVegetables
{
    HorseRadish,
    Radish,
    Turnip
}

// A bit field or flag enumeration of harvesting seasons.
[Flags]
public enum Seasons
{
    None = 0,
    Summer = 1,
    Autumn = 2,
    Winter = 4,
    Spring = 8,
    All = Summer | Autumn | Winter | Spring
}

public class Example
{
   public static void Main()
   {
       // Hash table of when vegetables are available.
       Dictionary<SomeRootVegetables, Seasons> AvailableIn = new Dictionary<SomeRootVegetables, Seasons>();

       AvailableIn[SomeRootVegetables.HorseRadish] = Seasons.All;
       AvailableIn[SomeRootVegetables.Radish] = Seasons.Spring;
       AvailableIn[SomeRootVegetables.Turnip] = Seasons.Spring |
            Seasons.Autumn;

       // Array of the seasons, using the enumeration.
       Seasons[] theSeasons = new Seasons[] { Seasons.Summer, Seasons.Autumn,
            Seasons.Winter, Seasons.Spring };

       // Print information of what vegetables are available each season.
       foreach (Seasons season in theSeasons)
       {
          Console.Write(String.Format(
              "The following root vegetables are harvested in {0}:\n",
              season.ToString("G")));
          foreach (KeyValuePair<SomeRootVegetables, Seasons> item in AvailableIn)
          {
             // A bitwise comparison.
             if (((Seasons)item.Value & season) > 0)
                 Console.Write(String.Format("  {0:G}\n",
                      (SomeRootVegetables)item.Key));
          }
       }
   }
}
// The example displays the following output:
//    The following root vegetables are harvested in Summer:
//      HorseRadish
//    The following root vegetables are harvested in Autumn:
//      Turnip
//      HorseRadish
//    The following root vegetables are harvested in Winter:
//      HorseRadish
//    The following root vegetables are harvested in Spring:
//      Turnip
//      Radish
//      HorseRadish
Imports System.Collections.Generic

' A traditional enumeration of some root vegetables.
Public Enum SomeRootVegetables
    HorseRadish
    Radish
    Turnip
End Enum

' A bit field or flag enumeration of harvesting seasons.
<Flags()> Public Enum Seasons
    None = 0
    Summer = 1
    Autumn = 2
    Winter = 4
    Spring = 8
    All = Summer Or Autumn Or Winter Or Spring
End Enum

' Entry point.
Public Class Example
    Public Shared Sub Main()
        ' Hash table of when vegetables are available.
        Dim AvailableIn As New Dictionary(Of SomeRootVegetables, Seasons)()

        AvailableIn(SomeRootVegetables.HorseRadish) = Seasons.All
        AvailableIn(SomeRootVegetables.Radish) = Seasons.Spring
        AvailableIn(SomeRootVegetables.Turnip) = Seasons.Spring Or _
                                                 Seasons.Autumn

        ' Array of the seasons, using the enumeration.
        Dim theSeasons() As Seasons = {Seasons.Summer, Seasons.Autumn, _
                                       Seasons.Winter, Seasons.Spring}

        ' Print information of what vegetables are available each season.
        For Each season As Seasons In theSeasons
            Console.WriteLine(String.Format( _
                 "The following root vegetables are harvested in {0}:", _
                 season.ToString("G")))
            For Each item As KeyValuePair(Of SomeRootVegetables, Seasons) In AvailableIn
                ' A bitwise comparison.
                If (CType(item.Value, Seasons) And season) > 0 Then
                    Console.WriteLine("  " + _
                          CType(item.Key, SomeRootVegetables).ToString("G"))
                End If
            Next
        Next
    End Sub
End Class
' The example displays the following output:
'    The following root vegetables are harvested in Summer:
'      HorseRadish
'    The following root vegetables are harvested in Autumn:
'      Turnip
'      HorseRadish
'    The following root vegetables are harvested in Winter:
'      HorseRadish
'    The following root vegetables are harvested in Spring:
'      Turnip
'      Radish
'      HorseRadish

Antarmuka

Antarmuka mendefinisikan kontrak yang menentukan hubungan "dapat melakukan" atau hubungan "memiliki". Antarmuka sering digunakan untuk mengimplementasikan fungsionalitas, seperti membandingkan dan mengurutkan (antarmuka IComparable dan IComparable<T>), pengujian untuk kesetaraan (antarmuka IEquatable<T>), atau menghitung item dalam koleksi (antarmuka IEnumerable dan IEnumerable<T>). Antarmuka dapat memiliki properti, metode, dan peristiwa, yang semuanya merupakan anggota abstrak; artinya, meskipun antarmuka mendefinisikan anggota dan tanda tangan mereka, antarmuka meninggalkannya ke jenis yang mengimplementasikan antarmuka untuk menentukan fungsionalitas setiap anggota antarmuka. Ini berarti bahwa setiap kelas atau struktur yang mengimplementasikan antarmuka harus menyediakan definisi untuk anggota abstrak yang dideklarasikan dalam antarmuka. Antarmuka dapat memerlukan kelas atau struktur penerapan apa pun untuk juga mengimplementasikan satu atau beberapa antarmuka lainnya.

Pembatasan berikut berlaku untuk kumpulan antarmuka:

  • Antarmuka dapat dideklarasikan dengan aksesibilitas apa pun, tetapi semua anggota antarmuka harus memiliki aksesibilitas publik.
  • Antarmuka tidak dapat menentukan konstruktor.
  • Antarmuka tidak dapat menentukan bidang.
  • Antarmuka hanya dapat menentukan anggota instans. Mereka tidak dapat mendefinisikan anggota statis.

Setiap bahasa harus menyediakan aturan untuk memetakan implementasi ke antarmuka yang memerlukan anggota, karena lebih dari satu antarmuka dapat mendeklarasikan anggota dengan tanda tangan yang sama, dan anggota ini dapat memiliki implementasi terpisah.

Delegasikan

Delegasi adalah jenis referensi yang melayani tujuan yang mirip dengan penunjuk fungsi di C++. Mereka digunakan untuk penanganan aktivitas dan fungsi panggilan balik di .NET. Tidak seperti penunjuk fungsi, delegasi aman, dapat diverifikasi, dan jenis aman. Jenis delegasi dapat mewakili metode instans atau metode statis apa pun yang memiliki tanda tangan yang kompatibel.

Parameter delegasi kompatibel dengan parameter metode yang sesuai jika jenis parameter delegasi lebih ketat daripada jenis parameter metode, karena ini menjamin bahwa argumen yang diteruskan ke delegasi dapat diteruskan dengan aman ke metode.

Demikian pula, jenis pengembalian delegasi kompatibel dengan jenis pengembalian metode jika jenis pengembalian metode lebih ketat daripada jenis pengembalian delegasi, karena ini menjamin bahwa nilai pengembalian metode dapat ditransmisikan dengan aman ke jenis pengembalian delegasi.

Misalnya, delegasi yang memiliki parameter jenis IEnumerable dan jenis pengembalian Object dapat mewakili metode yang memiliki parameter jenis Object dan nilai pengembalian jenis IEnumerable. Untuk informasi dan contoh selengkapnya, lihat Delegate.CreateDelegate(Type, Object, MethodInfo).

Delegasi dikatakan terikat dengan metode yang diwakilinya. Selain terikat dengan metode, delegasi dapat terikat ke objek. Objek mewakili parameter pertama metode, dan diteruskan ke metode setiap kali delegasi dipanggil. Jika metode adalah metode instans, objek terikat diteruskan sebagai parameter implisit this (Me dalam Visual Basic); jika metode statis, objek diteruskan sebagai parameter formal pertama dari metode, dan tanda tangan delegasi harus cocok dengan parameter yang tersisa. Untuk informasi dan contoh selengkapnya, lihat System.Delegate.

Semua delegasi mewarisi dari System.MulticastDelegate, yang mewarisi dari System.Delegate. Bahasa C#, Visual Basic, dan C++ tidak mengizinkan pewarisan dari jenis ini. Sebaliknya, mereka menyediakan kata kunci untuk mendeklarasikan delegasi.

Karena delegasi mewarisi dari MulticastDelegate, delegasi memiliki daftar pemanggilan, yang merupakan daftar metode yang diwakili delegasi dan yang dijalankan saat delegasi dipanggil. Semua metode dalam daftar menerima argumen yang disediakan saat delegasi dipanggil.

Catatan

Nilai yang dikembalikan tidak didefinisikan untuk delegasi yang memiliki lebih dari satu metode dalam daftar pemanggilannya, bahkan jika delegasi memiliki jenis pengembalian.

Dalam banyak kasus, seperti dengan metode panggilan balik, delegasi hanya mewakili satu metode, dan satu-satunya tindakan yang harus Anda ambil adalah membuat delegasi dan memanggilnya.

Untuk delegasi yang mewakili beberapa metode, .NET menyediakan metode Delegate dan MulticastDelegate mendelegasikan kelas untuk mendukung operasi seperti menambahkan metode ke daftar pemanggilan delegasi (metode Delegate.Combine), menghapus metode (metode Delegate.Remove), dan mendapatkan daftar pemanggilan (metode Delegate.GetInvocationList).

Catatan

Tidak perlu menggunakan metode ini untuk delegasi penanganan aktivitas di C#, C++, dan Visual Basic, karena bahasa ini menyediakan sintaks untuk menambahkan dan menghapus penanganan aktivitas.

Definisi Jenis

Definisi jenis mencakup yang berikut ini:

  • Atribut apa pun yang ditentukan pada jenis.
  • Aksesibilitas jenis (visibilitas).
  • Nama jenis.
  • Jenis dasar jenis.
  • Antarmuka apa pun yang diimplementasikan oleh jenis.
  • Definisi untuk setiap anggota jenis.

Atribut

Atribut menyediakan metadata tambahan yang ditentukan pengguna. Paling umum, mereka digunakan untuk menyimpan informasi tambahan tentang jenis di perakitannya, atau untuk memodifikasi perilaku anggota jenis baik di lingkungan waktu desain atau run-time.

Atribut adalah kelas itu sendiri yang mewarisi dari System.Attribute. Bahasa yang mendukung penggunaan atribut masing-masing memiliki sintaksnya sendiri untuk menerapkan atribut ke elemen bahasa. Atribut dapat diterapkan ke hampir semua elemen bahasa; elemen tertentu tempat atribut dapat diterapkan didefinisikan oleh AttributeUsageAttribute yang diterapkan ke kelas atribut tersebut.

Aksesibilitas jenis

Semua jenis memiliki pengubah yang mengatur aksesibilitasnya dari jenis lain. Tabel berikut ini menjelaskan jenis aksesibilitas yang didukung oleh runtime.

Aksesibilitas Deskripsi
publik Jenis ini dapat diakses oleh semua rakitan.
rakitan Jenis ini hanya dapat diakses dari dalam rakitannya.

Aksesibilitas jenis berlapis bergantung pada domain aksesibilitasnya, yang ditentukan oleh aksesibilitas yang dideklarasikan dari anggota dan domain aksesibilitas dari jenis yang berisi langsung. Namun, domain aksesibilitas jenis berlapis tidak dapat melebihi jenis yang memuatnya.

Domain aksesibilitas anggota berlapis M yang dideklarasikan dalam jenis T dalam program P didefinisikan sebagai berikut (mencatat bahwa M mungkin itu sendiri adalah jenis):

  • Jika aksesibilitas yang dideklarasikan M adalah public, domain aksesibilitas M adalah domain aksesibilitas T.

  • Jika aksesibilitas yang dideklarasikan M adalah protected internal, domain aksesibilitas M adalah persimpangan domain aksesibilitas T dengan teks program P dan teks program dari jenis apa pun yang berasal dari T yang dinyatakan di luar P.

  • Jika aksesibilitas yang dideklarasikan M adalah protected, domain aksesibilitas M adalah persimpangan domain aksesibilitas T dengan teks program T dan teks program dari jenis apa pun yang berasal dari T.

  • Jika aksesibilitas yang dideklarasikan M adalah internal, domain aksesibilitas M adalah persimpangan domain aksesibilitas T dengan teks program P.

  • Jika aksesibilitas yang dideklarasikan M adalah private, domain aksesibilitas M adalah teks program T.

Nama Jenis

Sistem jenis umum hanya memberlakukan dua batasan pada nama:

  • Semua nama dikodekan sebagai string karakter Unicode (16-bit).
  • Nama tidak diizinkan untuk memiliki nilai 0x0000 yang disematkan (16-bit).

Namun, sebagian besar bahasa memberlakukan pembatasan tambahan pada nama jenis. Semua perbandingan dilakukan secara byte-byte, dan karenanya peka huruf besar/kecil dan independen lokal.

Meskipun jenis mungkin mereferensikan jenis dari modul dan rakitan lain, jenis harus sepenuhnya ditentukan dalam satu modul .NET. (Namun, tergantung pada dukungan kompilator, dapat dibagi menjadi beberapa file kode sumber.) Nama jenis hanya perlu unik dalam namespace. Untuk sepenuhnya mengidentifikasi jenis, nama jenis harus memenuhi syarat oleh namespace yang berisi implementasi jenis.

Jenis dasar dan antarmuka

Jenis dapat mewarisi nilai dan perilaku dari jenis lain. Sistem jenis umum tidak mengizinkan jenis untuk mewarisi dari lebih dari satu jenis dasar.

Jenis dapat mengimplementasikan sejumlah antarmuka. Untuk mengimplementasikan antarmuka, jenis harus mengimplementasikan semua anggota virtual antarmuka tersebut. Metode virtual dapat diimplementasikan oleh jenis turunan dan dapat dipanggil baik secara statis maupun dinamis.

Anggota Jenis

Runtime memungkinkan Anda menentukan anggota jenis Anda, yang menentukan perilaku dan status jenis. Jenis anggota meliputi yang berikut ini:

Bidang

Bidang menjelaskan dan berisi bagian dari status jenis. Bidang bisa dari jenis apa pun yang didukung oleh runtime. Paling umum, bidang adalah private atau protected, sehingga hanya dapat diakses dari dalam kelas atau dari kelas turunan. Jika nilai bidang dapat dimodifikasi dari luar jenisnya, pengaktif set properti biasanya digunakan. Bidang yang diekspos secara publik biasanya baca-saja dan dapat terdiri dari dua jenis:

  • Konstanta, yang nilainya ditetapkan pada waktu desain. Ini adalah anggota statis kelas, meskipun mereka tidak didefinisikan menggunakan static kata kunci (Shared dalam Visual Basic).
  • Variabel baca-saja, yang nilainya dapat ditetapkan di konstruktor kelas.

Contoh berikut mengilustrasikan kedua penggunaan bidang baca-saja ini.

using System;

public class Constants
{
   public const double Pi = 3.1416;
   public readonly DateTime BirthDate;

   public Constants(DateTime birthDate)
   {
      this.BirthDate = birthDate;
   }
}

public class Example
{
   public static void Main()
   {
      Constants con = new Constants(new DateTime(1974, 8, 18));
      Console.Write(Constants.Pi + "\n");
      Console.Write(con.BirthDate.ToString("d") + "\n");
   }
}
// The example displays the following output if run on a system whose current
// culture is en-US:
//    3.1416
//    8/18/1974
Public Class Constants
    Public Const Pi As Double = 3.1416
    Public ReadOnly BirthDate As Date

    Public Sub New(birthDate As Date)
        Me.BirthDate = birthDate
    End Sub
End Class

Public Module Example
    Public Sub Main()
        Dim con As New Constants(#8/18/1974#)
        Console.WriteLine(Constants.Pi.ToString())
        Console.WriteLine(con.BirthDate.ToString("d"))
    End Sub
End Module
' The example displays the following output if run on a system whose current
' culture is en-US:
'    3.1416
'    8/18/1974

Properti

Properti menamai nilai atau status jenis dan menentukan metode untuk mendapatkan atau mengatur nilai properti. Properti dapat berupa jenis primitif, kumpulan jenis primitif, jenis yang ditentukan pengguna, atau koleksi jenis yang ditentukan pengguna. Properti sering digunakan untuk menjaga antarmuka publik jenis tetap independen dari representasi aktual jenis. Ini memungkinkan properti untuk mencerminkan nilai yang tidak secara langsung disimpan di kelas (misalnya, ketika properti mengembalikan nilai komputasi) atau untuk melakukan validasi sebelum nilai ditetapkan ke bidang privat. Contoh berikut menggambarkan pola ini.

using System;

public class Person
{
   private int m_Age;

   public int Age
   {
      get { return m_Age; }
      set {
         if (value < 0 || value > 125)
         {
            throw new ArgumentOutOfRangeException("The value of the Age property must be between 0 and 125.");
         }
         else
         {
            m_Age = value;
         }
      }
   }
}
Public Class Person
    Private m_Age As Integer

    Public Property Age As Integer
        Get
            Return m_Age
        End Get
        Set
            If value < 0 Or value > 125 Then
                Throw New ArgumentOutOfRangeException("The value of the Age property must be between 0 and 125.")
            Else
                m_Age = value
            End If
        End Set
    End Property
End Class

Selain menyertakan properti itu sendiri, bahasa perantara umum (CIL) untuk jenis yang berisi properti yang dapat dibaca mencakup get_metode nama properti, dan CIL untuk jenis yang berisi properti bisa-tulis menyertakan set_metode nama properti.

Metode

Metode menjelaskan operasi yang tersedia pada jenis. Tanda tangan metode menentukan jenis yang diizinkan dari semua parameternya dan nilai pengembaliannya.

Meskipun sebagian besar metode menentukan jumlah parameter yang tepat yang diperlukan untuk panggilan metode, beberapa metode mendukung jumlah parameter variabel. Parameter akhir yang dinyatakan dari metode ini ditandai dengan ParamArrayAttribute atribut. Kompilator bahasa biasanya menyediakan kata kunci, seperti params di C# dan ParamArray dalam Visual Basic, yang membuat penggunaan eksplisit ParamArrayAttribute tidak perlu.

Konstruktor

Konstruktor adalah jenis metode khusus yang membuat instans baru dari kelas atau struktur. Seperti metode lainnya, konstruktor dapat menyertakan parameter; namun, konstruktor tidak memiliki nilai pengembalian (yaitu, mereka mengembalikan void).

Jika kode sumber untuk kelas tidak secara eksplisit menentukan konstruktor, kompilator menyertakan konstruktor tanpa parameter. Namun, jika kode sumber untuk kelas hanya mendefinisikan konstruktor berparameter, kompilator Visual Basic dan C# tidak menghasilkan konstruktor tanpa parameter.

Jika kode sumber untuk struktur mendefinisikan konstruktor, mereka harus diparameterkan; struktur tidak dapat menentukan konstruktor tanpa parameter, dan kompilator tidak menghasilkan konstruktor tanpa parameter untuk struktur atau jenis nilai lainnya. Semua jenis nilai memang memiliki konstruktor tanpa parameter implisit. Konstruktor ini diimplementasikan oleh runtime bahasa umum dan menginisialisasi semua bidang struktur ke nilai defaultnya.

Acara

Peristiwa mendefinisikan insiden yang dapat direspons, dan menentukan metode untuk berlangganan, berhenti berlangganan dari, dan menaikkan peristiwa. Peristiwa sering digunakan untuk menginformasikan jenis perubahan status lainnya. Untuk informasi selengkapnya, lihat Peristiwa.

Jenis Berlapis

Jenis berlapis adalah jenis yang merupakan anggota dari beberapa jenis lainnya. Jenis berlapis harus digabungkan erat dengan jenis yang berisi dan tidak boleh berguna sebagai jenis tujuan umum. Jenis berlapis berguna saat jenis deklarasikan menggunakan dan membuat instans jenis berlapis, dan penggunaan jenis berlapis tidak diekspos di anggota publik.

Jenis berlapis membingungkan bagi beberapa pengembang dan tidak boleh terlihat secara publik kecuali ada alasan yang menarik untuk visibilitas. Dalam pustaka yang dirancang dengan baik, pengembang jarang harus menggunakan jenis berlapis untuk membuat instans objek atau mendeklarasikan variabel.

Karakteristik anggota tipe

Sistem jenis umum memungkinkan anggota jenis untuk memiliki berbagai karakteristik; namun, bahasa tidak diperlukan untuk mendukung semua karakteristik ini. Tabel berikut ini menjelaskan karakteristik.

Karakteristik Dapat berlaku untuk Deskripsi
abstrak Metode, properti, dan peristiwa Jenis ini tidak menyediakan implementasi metode. Jenis yang mewarisi atau menerapkan metode abstrak harus menyediakan implementasi untuk metode tersebut. Satu-satunya pengecualian adalah ketika jenis turunan itu sendiri adalah jenis abstrak. Semua metode abstrak bersifat virtual.
privat, keluarga, perakitan, keluarga dan perakitan, keluarga atau perakitan, atau publik Semua Menentukan aksesibilitas anggota:

privat
Hanya dapat diakses dari dalam jenis yang sama dengan anggota, atau dalam jenis berlapis.

keluarga
Dapat diakses dari dalam jenis yang sama dengan anggota, dan dari jenis turunan yang mewarisinya.

rakitan
Hanya dapat diakses di rakitan tempat jenis didefinisikan.

keluarga dan perakitan
Hanya dapat diakses dari jenis yang memenuhi syarat untuk akses keluarga dan perakitan.

keluarga atau perakitan
Hanya dapat diakses dari jenis yang memenuhi syarat untuk akses keluarga atau perakitan.

publik
Dapat diakses dari jenis apa pun.
final Metode, properti, dan peristiwa Metode virtual tidak dapat ditimpa dalam jenis turunan.
inisialisasi-saja Bidang Nilai hanya dapat diinisialisasi, dan tidak dapat ditulis setelah inisialisasi.
instance Bidang, metode, properti, dan kejadian Jika anggota tidak ditandai sebagai static (C# dan C++), Shared (Visual Basic), virtual (C# dan C++), atau Overridable (Visual Basic), itu adalah anggota instans (tidak ada kata kunci instans). Akan ada sebanyak salinan anggota tersebut dalam memori karena ada objek yang menggunakannya.
harfiah Bidang Nilai yang ditetapkan ke bidang adalah nilai tetap, yang diketahui pada waktu kompilasi, dari jenis nilai bawaan. Bidang harfiah terkadang disebut sebagai konstanta.
newslot atau ambil alih Semua Menentukan bagaimana anggota berinteraksi dengan anggota yang diwariskan yang memiliki tanda tangan yang sama:

newslot
Menyembunyikan anggota yang diwariskan yang memiliki tanda tangan yang sama.

ambil alih
Menggantikan definisi metode virtual yang diwariskan.

Defaultnya adalah newslot.
statik Bidang, metode, properti, dan kejadian Anggota termasuk dalam jenis yang didefinisikannya, bukan untuk instans tertentu dari jenis; anggota ada bahkan jika instans jenis tidak dibuat, dan dibagikan di antara semua instans jenis.
virtual Metode, properti, dan peristiwa Metodenya dapat diimplementasikan oleh jenis turunan dan dapat dipanggil baik secara statis maupun dinamis. Jika pemanggilan dinamis digunakan, jenis instans yang melakukan panggilan pada durasi (bukan jenis yang diketahui pada waktu kompilasi) menentukan implementasi metode mana yang dipanggil. Untuk memanggil metode virtual secara statis, variabel mungkin harus ditransmisikan ke jenis yang menggunakan versi metode yang diinginkan.

Kelebihan beban

Setiap anggota jenis memiliki tanda tangan unik. Tanda tangan metode terdiri dari nama metode dan daftar parameter (urutan dan jenis argumen metode). Beberapa metode dengan nama yang sama dapat didefinisikan dalam jenis selama tanda tangannya berbeda. Ketika dua metode atau lebih dengan nama yang sama didefinisikan, metode ini dikatakan kelebihan beban. Misalnya, dalam System.Char, metode IsDigit kelebihan beban. Satu metode mengambil Char. Metode lain mengambil String dan Int32.

Catatan

Jenis pengembalian tidak dianggap sebagai bagian dari tanda tangan metode. Artinya, metode tidak dapat kelebihan beban jika hanya berbeda dengan jenis pengembalian.

Mewarisi, mengambil alih, dan menyembunyikan anggota

Jenis turunan mewarisi semua anggota dari jenis dasarnya; artinya, anggota ini didefinisikan pada, dan tersedia untuk, jenis turunannya. Perilaku atau kualitas anggota yang diwariskan dapat dimodifikasi dengan dua cara:

  • Jenis turunan dapat menyembunyikan anggota yang diwariskan dengan menentukan anggota baru dengan tanda tangan yang sama. Ini mungkin dilakukan untuk membuat anggota publik sebelumnya privat atau untuk menentukan perilaku baru untuk metode yang diwariskan yang ditandai sebagai final.

  • Jenis turunan dapat mengambil alih metode virtual yang diwariskan. Metode penimpaan memberikan definisi baru dari metode yang akan dipanggil berdasarkan jenis nilai pada durasi daripada jenis variabel yang diketahui pada waktu kompilasi. Metode dapat mengambil alih metode virtual hanya jika metode virtual tidak ditandai sebagai final dan metode baru setidaknya dapat diakses sebagai metode virtual.

Lihat juga