Metode (Panduan Pemrograman C#)
Metode adalah blok kode yang berisi serangkaian pernyataan. Sebuah program menyebabkan pernyataan dieksekusi dengan memanggil metode dan menentukan argumen metode yang diperlukan. Di C#, setiap instruksi yang dijalankan dilakukan dalam konteks metode.
Metode Main
ini adalah titik masuk untuk setiap aplikasi C# dan dipanggil oleh runtime bahasa umum (CLR) ketika program dimulai. Dalam aplikasi yang menggunakan pernyataan tingkat atas, metode Main
ini dihasilkan oleh kompilator dan berisi semua pernyataan tingkat atas.
Catatan
Artikel ini membahas metode bernama. Untuk informasi tentang fungsi anonim, lihat Ekspresi Lambda .
Tanda tangan metode
Metode dideklarasikan dalam kelas, struktur, atau antarmuka dengan menentukan tingkat akses seperti public
atau private
, pengubah opsional seperti abstract
atau sealed
, nilai pengembalian, nama metode, dan parameter metode apa pun. Bagian-bagian ini bersama-sama adalah tanda tangan metode.
Penting
Jenis pengembalian metode bukan bagian dari tanda tangan metode untuk tujuan metode kelebihan beban. Namun, ini adalah bagian dari tanda tangan metode saat menentukan kompatibilitas antara delegasi dan metode yang ditunjukkannya.
Parameter metode diapit dalam tanda kurung dan dipisahkan dengan koma. Tanda kurung kosong menunjukkan bahwa metode tidak memerlukan parameter. Kelas ini berisi empat metode:
abstract class Motorcycle
{
// Anyone can call this.
public void StartEngine() {/* Method statements here */ }
// Only derived classes can call this.
protected void AddGas(int gallons) { /* Method statements here */ }
// Derived classes can override the base class implementation.
public virtual int Drive(int miles, int speed) { /* Method statements here */ return 1; }
// Derived classes must implement this.
public abstract double GetTopSpeed();
}
Akses metode
Memanggil metode pada objek seperti mengakses bidang. Setelah nama objek, tambahkan titik, nama metode, dan tanda kurung. Argumen dicantumkan dalam tanda kurung dan dipisahkan dengan koma. Oleh karena itu, metode kelas Motorcycle
dapat dipanggil seperti dalam contoh berikut:
class TestMotorcycle : Motorcycle
{
public override double GetTopSpeed()
{
return 108.4;
}
static void Main()
{
TestMotorcycle moto = new TestMotorcycle();
moto.StartEngine();
moto.AddGas(15);
moto.Drive(5, 20);
double speed = moto.GetTopSpeed();
Console.WriteLine("My top speed is {0}", speed);
}
}
Metode parameter vs argumen
Definisi metode menentukan nama dan jenis parameter apa pun yang diperlukan. Ketika memanggil kode panggilan metode, pemanggil menyediakan nilai konkret, yang disebut argumen, untuk setiap parameter. Argumen harus kompatibel dengan jenis parameter, tetapi nama argumen (jika ada), jika argumen digunakan dalam kode panggilan, tidak harus sama dengan parameter bernama yang ditentukan dalam metode. Contohnya:
public void Caller()
{
int numA = 4;
// Call with an int variable.
int productA = Square(numA);
int numB = 32;
// Call with another int variable.
int productB = Square(numB);
// Call with an integer literal.
int productC = Square(12);
// Call with an expression that evaluates to int.
productC = Square(productA * 3);
}
int Square(int i)
{
// Store input argument in a local variable.
int input = i;
return input * input;
}
Melewati referensi vs melewati nilai
Secara default, ketika instans jenis nilai diteruskan ke metode, salinannya diteruskan alih-alih instans itu sendiri. Oleh karena itu, perubahan pada argumen tidak berpengaruh pada instans asli dalam metode pemanggilan. Untuk meneruskan instans jenis nilai berdasarkan referensi, gunakan kata kunci ref
. Untuk informasi selengkapnya, lihat Meneruskan Parameter Value-Type.
Ketika objek dari jenis referensi diteruskan ke metode, referensi ke objek diteruskan. Artinya, metode ini tidak menerima objek itu sendiri, tetapi argumen yang menunjukkan lokasi objek. Jika Anda mengubah anggota objek dengan menggunakan referensi ini, perubahan tercermin dalam argumen dalam metode panggilan, bahkan jika Anda melewatkan objek berdasarkan nilai.
Anda membuat jenis referensi dengan menggunakan kata kunci class
, seperti yang ditunjukkan contoh berikut:
public class SampleRefType
{
public int value;
}
Sekarang, jika Anda meneruskan objek yang didasarkan pada jenis ini ke metode, referensi ke objek akan diteruskan. Contoh berikut meneruskan objek jenis SampleRefType
ke metode ModifyObject
:
public static void TestRefType()
{
SampleRefType rt = new SampleRefType();
rt.value = 44;
ModifyObject(rt);
Console.WriteLine(rt.value);
}
static void ModifyObject(SampleRefType obj)
{
obj.value = 33;
}
Contoh ini pada dasarnya melakukan hal yang sama seperti contoh sebelumnya, ini meneruskan argumen berdasarkan nilai ke suatu metode. Tetapi karena jenis referensi yang digunakan, hasilnya berbeda. Modifikasi yang dilakukan pada ModifyObject
ke bidang parameter value
, obj
, juga mengubah bidang argumen value
, rt
, dalam metode TestRefType
. Metode TestRefType
menampilkan 33 sebagai output.
Untuk informasi selengkapnya tentang cara meneruskan jenis referensi menurut referensi dan berdasarkan nilai, lihat Meneruskan Parameter Reference-Type dan Jenis Referensi.
Mengembalikan nilai
Metode dapat mengembalikan nilai ke pemanggil. Jika jenis pengembalian (jenis yang dicantumkan sebelum nama metode) bukan void
, metode dapat mengembalikan nilai dengan menggunakan kata kunci return
statement. Pernyataan dengan kata kunci return
diikuti oleh variabel, yang cocok dengan jenis pengembalian akan mengembalikan nilai tersebut ke pemanggil metode.
Nilai dapat dikembalikan ke pemanggil berdasarkan nilai atau dengan referensi. Nilai dikembalikan ke pemanggil dengan referensi jika kata kunci ref
digunakan dalam tanda tangan metode dan mengikuti setiap kata kunci return
. Misalnya, metode berikut tanda tangan dan pernyataan pengembalian menunjukkan bahwa metode mengembalikan variabel bernama estDistance
dengan referensi ke pemanggil.
public ref double GetEstimatedDistance()
{
return ref estDistance;
}
Kata kunci return
juga menghentikan eksekusi metode. Jika jenis pengembaliannya adalah void
, pernyataan return
tanpa nilai masih berguna untuk menghentikan eksekusi metode. Tanpa kata kunci return
, metode akan berhenti mengeksekusi ketika mencapai akhir blok kode. Metode dengan jenis pengembalian yang tidak batal diperlukan untuk menggunakan kata kunci return
untuk mengembalikan nilai. Misalnya, dua metode ini menggunakan kata kunci return
untuk mengembalikan bilangan bulat:
class SimpleMath
{
public int AddTwoNumbers(int number1, int number2)
{
return number1 + number2;
}
public int SquareANumber(int number)
{
return number * number;
}
}
Untuk menggunakan nilai yang dikembalikan dari metode, metode panggilan dapat menggunakan metode memanggil dirinya sendiri di mana saja nilai dengan jenis yang sama akan cukup. Anda juga dapat menetapkan nilai yang dikembalikan ke variabel. Misalnya, dua contoh kode berikut mencapai tujuan yang sama:
int result = obj.AddTwoNumbers(1, 2);
result = obj.SquareANumber(result);
// The result is 9.
Console.WriteLine(result);
result = obj.SquareANumber(obj.AddTwoNumbers(1, 2));
// The result is 9.
Console.WriteLine(result);
Menggunakan variabel lokal, dalam hal ini, result
, untuk menyimpan nilai bersifat opsional. Ini dapat membantu keterbacaan kode, atau mungkin diperlukan jika Anda perlu menyimpan nilai asli argumen untuk seluruh cakupan metode.
Untuk menggunakan nilai yang dikembalikan oleh referensi dari metode, Anda harus mendeklarasikan variabel lokal ref jika Anda berniat untuk mengubah nilainya. Misalnya, jika metode Planet.GetEstimatedDistance
mengembalikan nilai Double menurut referensi, Anda dapat menentukannya sebagai variabel lokal ref dengan kode seperti berikut:
ref double distance = ref Planet.GetEstimatedDistance();
Mengembalikan array multidimensi dari metode, M
, yang memodifikasi konten array tidak diperlukan jika fungsi panggilan meneruskan array ke M
. Anda dapat mengembalikan array yang dihasilkan dari M
untuk gaya yang baik atau aliran nilai yang berfungsi, tetapi tidak diperlukan karena C# meneruskan semua jenis referensi menurut nilai, dan nilai referensi array adalah penunjuk ke array. Dalam metode M
, setiap perubahan pada konten array dapat diamati oleh kode apa pun yang memiliki referensi ke array, seperti yang ditunjukkan pada contoh berikut:
static void Main(string[] args)
{
int[,] matrix = new int[2, 2];
FillMatrix(matrix);
// matrix is now full of -1
}
public static void FillMatrix(int[,] matrix)
{
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
matrix[i, j] = -1;
}
}
}
Metode asinkron
Dengan menggunakan fitur asinkron, Anda dapat memanggil metode asinkron tanpa menggunakan panggilan balik eksplisit atau secara manual memisahkan kode Anda di beberapa metode atau ekspresi lambda.
Jika Anda menandai metode dengan pengubah asinkron, Anda dapat menggunakan operator menunggu dalam metode tersebut. Ketika kontrol mencapai ekspresi menunggu dalam metode async, kontrol kembali ke pemanggil, dan kemajuan dalam metode ditangguhkan hingga tugas yang ditunggu selesai. Ketika tugas selesai, eksekusi dapat dilanjutkan dalam metode.
Catatan
Metode asinkron kembali ke pemanggil ketika menemukan objek pertama yang ditunggu yang belum selesai atau sampai ke akhir metode asinkron, mana yang terjadi terlebih dahulu.
Metode asinkron biasanya memiliki jenis pengembalian, Task<TResult>, TaskIAsyncEnumerable<T>atau void
. Jenis pengembalian void
digunakan terutama untuk menentukan penanganan aktivitas, di mana jenis pengembalian void
diperlukan. Metode asinkron yang memiliki jenis pengembalian void
tidak dapat ditunggu, dan pemanggil metode pengembalian void tidak dapat menangkap pengecualian apa pun yang ditampilkan metode tersebut. Metode asinkron dapat memiliki jenis pengembalian seperti tugas.
Dalam contoh berikut, DelayAsync
adalah metode asinkron yang memiliki jenis pengembalian Task<TResult>. DelayAsync
memiliki pernyataan return
yang mengembalikan bilangan bulat. Oleh karena itu deklarasi metode DelayAsync
harus memiliki jenis pengembalian Task<int>
. Karena jenis yang dikembalikan adalah Task<int>
, evaluasi ekspresi await
dalam DoSomethingAsync
menghasilkan bilangan bulat, seperti yang ditunjukkan oleh pernyataan berikut: int result = await delayTask
.
Metode Main
ini adalah contoh metode asinkron yang memiliki jenis pengembalian Task. Itu menuju ke metode DoSomethingAsync
, dan karena diekspresikan dengan satu baris, itu dapat menghilangkan kata kunci async
dan await
. Karena DoSomethingAsync
adalah metode asinkron, tugas untuk panggilan DoSomethingAsync
harus ditunggu, seperti yang ditunjukkan oleh pernyataan berikut: await DoSomethingAsync();
.
class Program
{
static Task Main() => DoSomethingAsync();
static async Task DoSomethingAsync()
{
Task<int> delayTask = DelayAsync();
int result = await delayTask;
// The previous two statements may be combined into
// the following statement.
//int result = await DelayAsync();
Console.WriteLine($"Result: {result}");
}
static async Task<int> DelayAsync()
{
await Task.Delay(100);
return 5;
}
}
// Example output:
// Result: 5
Metode asinkron tidak dapat mendeklarasikan parameter ref atau out, tetapi dapat memanggil metode yang memiliki parameter tersebut.
Untuk informasi selengkapnya tentang metode asinkron, lihat Pemrograman asinkron dengan asinkron dan menunggu dan Jenis pengembalian asinkron.
Definisi isi ekspresi
Memiliki definisi metode yang langsung kembali dengan hasil ekspresi, atau yang memiliki satu pernyataan sebagai isi metode adalah hal yang umum. Ada pintasan sintaks untuk mendefinisikan metode tersebut menggunakan =>
:
public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public void Print() => Console.WriteLine(First + " " + Last);
// Works with operators, properties, and indexers too.
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);
Jika metode mengembalikan void
atau merupakan metode asinkron, isi metode harus berupa ekspresi pernyataan (sama seperti lambda). Untuk properti dan pengindeks, mereka harus baca-saja, dan Anda tidak menggunakan kata kunci pengakses get
.
Iterator
Iterator melakukan perulangan kustom pada koleksi, seperti daftar atau array. Iterator menggunakan pernyataan yield return untuk mengembalikan setiap elemen satu per satu. Saat pernyataan yield return
pengembalian tercapai, lokasi saat ini dalam kode diingat. Eksekusi dimulai ulang dari lokasi tersebut saat iterator dipanggil lain kali.
Anda memanggil iterator dari kode klien dengan menggunakan pernyataan foreach.
Jenis pengembalian iterator dapat berupa IEnumerable, , IEnumerable<T>, IAsyncEnumerable<T>IEnumerator, atau IEnumerator<T>.
Untuk informasi selengkapnya, lihat Iterator.
Spesifikasi bahasa C#
Untuk informasi selengkapnya, lihat Spesifikasi Bahasa C#. Spesifikasi bahasa adalah sumber definitif untuk sintaks dan penggunaan C#.