Method adalah blok kode bernama yang menerima input (parameter), melakukan pekerjaannya, dan bisa menyerahkan kembali sebuah hasil (nilai kembalian). Di C#, setiap method berada di dalam sebuah tipe; tidak ada fungsi yang berdiri sendiri.
Output:
Headphones 48.00
Cable 11.40
Anatomi sebuah method
public static decimal PriceWithTax(decimal net, decimal taxRate)
{
return net * (1 + taxRate);
}
- Access modifier (
public,private, ...): siapa yang boleh memanggilnya. Kalau tidak ditulis, method bersifatprivateuntuk tipenya. static: method ini milik tipe, bukan milik sebuah objek. Penjelasannya ada di bawah.- Tipe kembalian: tipe nilai yang dikembalikannya, atau
voidkalau tidak ada. - Nama: menurut kebiasaan memakai PascalCase, biasanya kata kerja (
Calculate,SendEmail,TryParse). - Daftar parameter: nol atau lebih pasangan
type name. Setiap parameter adalah variabel lokal yang diisi dari argumen pemanggil. - Badan: pernyataan-pernyataan di antara kurung kurawal.
Nama ditambah tipe-tipe parameternya (dan modifier ref, out atau in kalau ada) membentuk signature method. Tipe kembalian bukan bagian dari signature, dan ini penting untuk overloading.
Nilai kembalian dan void
return langsung mengakhiri method dan menyerahkan kembali sebuah nilai. Method yang punya tipe kembalian harus mengembalikan nilai bertipe itu di setiap jalur yang melewatinya:
static string Grade(int score)
{
if (score >= 50)
return "pass";
} // error CS0161: 'Program.Grade(int)': not all code paths return a value
Compiler memeriksa setiap cabang. Tambahkan return "fail"; yang kurang, atau throw kalau sampai di titik itu berarti ada bug.
Method void tidak mengembalikan apa pun. Method itu tetap bisa memakai return; saja untuk keluar lebih awal:
Output:
ana@mail.com: newsletter sent
ben@mail.com: not subscribed, skipped
False
True
Expression-bodied method
Saat badan sebuah method hanya berupa satu ekspresi, => menggantikan kurung kurawal dan return:
static decimal Discount(decimal price) => price * 0.1m;
static bool IsAdult(int age) => age >= 18;
static void Log(string message) => Console.WriteLine($"[log] {message}");
Ini method yang sama, hanya ditulis lebih singkat. Bentuk ini juga bisa dipakai untuk method void, selama badannya hanya satu ekspresi (sebuah pemanggilan, sebuah pemberian nilai).
Parameter adalah salinan
Secara default, argumen dikirim berdasarkan nilai: parameter menerima salinan dari argumen. Memberi nilai baru ke parameter di dalam method tidak memengaruhi variabel milik pemanggil:
Output:
inside: 42
after: 21
scores: 70, 85, 100
List-nya berubah karena untuk reference type, nilai yang disalin adalah referensinya: method dan pemanggilnya menunjuk ke objek list yang sama. Memberikan scores = new List<int>() di dalam method tidak akan memengaruhi pemanggil. Agar sebuah method bisa memberi nilai ke variabel milik pemanggil, pakai ref atau out; untuk memberi nilai default pada parameter dan memanggilnya berdasarkan nama, pakai optional parameter dan named argument.
Mengembalikan beberapa nilai dengan tuple
Sejak C# 7.0, method bisa mengembalikan tuple dengan elemen bernama, dan pemanggil bisa mendekonstruksinya menjadi variabel-variabel terpisah:
Output:
min 15, max 27, avg 21.0
range 12
_ membuang elemen yang tidak kamu butuhkan. Untuk hasil yang dipakai di banyak tempat, class kecil atau record dengan property bernama menjelaskan bentuknya lebih baik daripada tuple.
Overloading
Beberapa method bisa memakai nama yang sama kalau daftar parameternya berbeda dalam jumlah, tipe atau urutan tipenya. Compiler memilih yang paling cocok untuk setiap pemanggilan:
Output:
12.57
13.50
25
Area(5) memilih versi int karena cocok persis; Area(2.0) memilih versi double. Method tidak boleh berbeda hanya pada tipe kembaliannya: dua method Area(int) yang mengembalikan int dan double adalah error CS0111, Type 'Program' already defines a member called 'Area' with the same parameter types, karena pemanggilan seperti Area(5) tidak bisa membedakan keduanya.
Pemanggilan yang tidak diterima overload mana pun juga gagal saat compile: Area(1, 2, 3) adalah CS1501, No overload for method 'Area' takes 3 arguments, dan Area("big") adalah CS1503, Argument 1: cannot convert from 'string' to 'double'.
params: jumlah argumen yang bervariasi
Parameter array params menerima argumen sebanyak apa pun, termasuk tanpa argumen. Compiler membuatkan array-nya untukmu:
Output:
empty cart: 0 item(s), 0
one item: 1 item(s), 9.99
three items: 3 item(s), 19.75
from array: 2 item(s), 50
Aturannya: params harus menjadi parameter terakhir (kalau tidak, CS0231), sebuah method paling banyak punya satu, dan mengirim array yang sudah ada akan menyerahkan array itu apa adanya. Console.WriteLine("{0} and {1}", a, b) dan string.Format adalah method params object[]. C# 13 memperluas params ke tipe koleksi lain seperti List<T> dan ReadOnlySpan<T>; sebelumnya, hanya array yang diizinkan.
Method static dan instance
Method static adalah milik tipe dan dipanggil lewat nama tipenya: Math.Max(3, 7), Program.Total(...). Method instance adalah milik sebuah objek dan bisa memakai field objek itu:
Output:
12
Memanggil method instance dari method static tanpa objek adalah error pemula yang paling umum di C#:
class Program
{
void Greet() => Console.WriteLine("hi");
static void Main()
{
Greet();
// error CS0120: An object reference is required for the non-static field, method, or property 'Program.Greet()'
}
}
Tandai Greet sebagai static, atau buat objek lalu panggil method itu lewat objek tersebut: new Program().Greet();. Halaman static membahas member static dan static class lebih dalam.
Method Main
Main adalah tempat program dimulai. Method ini harus static, dan signature berikut valid:
static void Main() { }
static void Main(string[] args) { } // command-line arguments
static int Main(string[] args) { return 0; } // exit code for the shell
static async Task Main() { } // C# 7.1 and later
Bentuk async Task Main membuat titik masuk bisa langsung melakukan await (lihat async dan await). Sejak C# 9, sebuah file bisa berisi top-level statements sebagai gantinya: kode tanpa class atau Main sama sekali, seperti di proyek baru dari dotnet new console. Compiler membuatkan class dan method Main di sekitarnya, jadi hasilnya sama saja, hanya ditulis lebih singkat; args tetap tersedia.
Rekursi
Sebuah method bisa memanggil dirinya sendiri. Setiap pemanggilan mendapat parameter dan variabel lokalnya sendiri, dan sebuah base case harus menghentikan rantainya:
Output:
120
2432902008176640000
35
Tanpa base case, atau dengan input yang terlalu dalam, setiap pemanggilan menambah satu stack frame sampai program mati dengan StackOverflowException. Exception itu tidak bisa ditangkap, jadi untuk input yang kedalamannya tidak diketahui, tulis ulang rekursinya sebagai loop.
Local function
C# 7.0 memperkenalkan local function: method yang dideklarasikan di dalam method lain dan hanya terlihat di sana. Local function bisa memakai variabel milik method yang membungkusnya:
// C# 7.0 and later
static int CountValid(string[] codes)
{
int count = 0;
foreach (string code in codes)
{
if (IsValid(code)) count++;
}
return count;
bool IsValid(string c) => c.Length == 6 && char.IsLetter(c[0]);
}
Local function menjaga fungsi bantu tetap berada di dekat satu-satunya pemanggilnya tanpa memperlihatkannya ke bagian lain class. Sejak C# 8, local function bisa ditandai static untuk melarangnya menangkap variabel dari luar. Di tempat local function tidak tersedia, method private static di class yang sama melakukan pekerjaan yang sama, seperti di contoh-contoh lain pada halaman ini.
Pertanyaan yang sering diajukan
Apa perbedaan method dan fungsi di C#?
Di C#, setiap fungsi dideklarasikan di dalam class, struct atau record, dan disebut method. Tidak ada fungsi yang berdiri sendiri. Bahkan top-level statements (C# 9) dan local function (C# 7) di-compile menjadi method dari tipe yang dibuatkan compiler atau tipe yang membungkusnya. Kata "fungsi" dipakai secara tidak resmi, juga untuk lambda dan delegate.
Apa yang dilakukan params di C#?
params membuat method bisa menerima jumlah argumen yang bervariasi dengan satu tipe: static int Sum(params int[] numbers) bisa dipanggil sebagai Sum(), Sum(4), Sum(4, 5, 6) atau Sum(existingArray). Compiler mengemas argumen-argumen itu ke dalam sebuah array. Parameter params harus menjadi parameter terakhir, dan sebuah method hanya boleh punya satu.
Apa itu method Main di C#?
Main adalah titik masuk program: method yang pertama kali dipanggil runtime. Method ini harus static, bisa mengembalikan void atau int (kode keluar), dan bisa menerima string[] args untuk argumen baris perintah. Sejak C# 7.1 bentuknya juga bisa async Task Main, dan sejak C# 9 top-level statements membuat compiler bisa membuatkannya untukmu.
Bagaimana cara mengembalikan beberapa nilai dari method C#?
Kembalikan sebuah tuple: static (int Min, int Max) Range(int[] values) dan return (min, max);. Pemanggil bisa membaca result.Min atau melakukan dekonstruksi dengan var (lo, hi) = Range(values);. Untuk nilai-nilai yang selalu bepergian bersama di seluruh kodemu, class atau record kecil lebih jelas; parameter out adalah alternatif yang lebih lama.
Kenapa muncul "An object reference is required for the non-static field, method, or property"?
Method static seperti Main memanggil method instance secara langsung. Method static adalah milik tipe dan tidak punya objek untuk dipakai memanggil method itu. Tandai method yang dipanggil sebagai static, atau buat objek terlebih dahulu: var app = new Program(); app.Greet();.
Apa arti "not all code paths return a value"?
Error CS0161: method yang punya tipe kembalian memiliki setidaknya satu jalur yang sampai ke kurung kurawal penutup tanpa return. Biasanya sebuah if mengembalikan nilai tapi tidak ada else atau return terakhir setelahnya. Tambahkan return (atau throw) di akhir method.