0Pricing
C# Academy · Pelajaran

Resolusi Metode Ekstensi

Pahami cara compiler menemukan ekstensi.

Resolusi Metode Ekstensi adalah pelajaran C# Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C# Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C# Academy mencakup 4 pelajaran total.

Bagaimana Kompiler Menemukan Ekstensi

Saat Anda menulis value.Method() dan tidak ada metode instans yang cocok, kompiler mencari metode ekstensi. Namun, kompiler hanya mempertimbangkan ekstensi yang ruang nama pemuatnya berada dalam cakupan melalui direktif using.

Direktif using Membawa Ekstensi ke Dalam Cakupan

Ekstensi hanya terlihat jika Anda mengimpor ruang namanya. Tanpa using yang tepat, metode tersebut tampak tidak ada meskipun sudah dikompilasi ke dalam rakitan.

using System;
using MyHelpers; // brings StringExtensions into scope

namespace MyHelpers
{
    public static class StringExtensions
    {
        public static string Reverse(this string s)
        {
            var arr = s.ToCharArray();
            Array.Reverse(arr);
            return new string(arr);
        }
    }
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine("hello".Reverse());
    }
}

Metode Instans Diperiksa Lebih Dahulu

Kompiler menyelesaikan pemanggilan secara bertahap: pertama, kompiler mencari metode instans yang cocok, termasuk metode yang diwariskan. Hanya jika tidak ada yang sesuai, kompiler mencari metode ekstensi.

using System;
using System.Collections.Generic;

public static class ListExt
{
    // Ignored: List<int> already has Add(int)
    public static void Add(this List<int> list, int a, int b)
        => list.Add(a + b);
}

public class Program
{
    public static void Main()
    {
        var list = new List<int>();
        list.Add(5); // the built-in instance Add wins for this signature
        Console.WriteLine(list[0]);
    }
}

Ruang Nama yang Lebih Dekat Diprioritaskan

Jika dua ekstensi cocok, ekstensi yang ruang namanya lebih dekat dalam hierarki bersarang akan dipilih. Ambiguitas yang tidak dapat diatasi oleh kompiler menyebabkan galat kompilasi dan memaksa Anda menghilangkan ambiguitas tersebut.

using System;

namespace Outer
{
    public static class A { public static string Tag(this int n) => "A" + n; }

    namespace Inner
    {
        public static class B { public static string Tag(this int n) => "B" + n; }

        public class Program
        {
            public static void Main()
            {
                // B is in the nearer (Inner) namespace, so it is preferred
                Console.WriteLine(7.Tag());
            }
        }
    }
}

Menghilangkan Ambiguitas dengan Pemanggilan Statis

Saat ekstensi saling bertentangan atau Anda ingin menyatakannya secara eksplisit, panggil metode statis secara langsung menggunakan nama kelas lengkapnya. Cara ini sepenuhnya melewati resolusi ekstensi.

using System;

public static class FormatExt
{
    public static string Bracket(this string s) => "[" + s + "]";
}

public class Program
{
    public static void Main()
    {
        // Explicit static call, no ambiguity possible
        Console.WriteLine(FormatExt.Bracket("x"));
    }
}

Resolusi Kelebihan Beban di Antara Ekstensi

Jika beberapa metode ekstensi memiliki nama yang sama, resolusi kelebihan beban normal akan memilih kecocokan terbaik berdasarkan tipe parameter, seperti pada kelebihan beban metode biasa.

using System;

public static class PrintExt
{
    public static string Describe(this int n) => "int:" + n;
    public static string Describe(this string s) => "str:" + s;
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine(42.Describe());
        Console.WriteLine("hi".Describe());
    }
}

Inferensi Generik Saat Resolusi

Untuk ekstensi generik, kompiler menyimpulkan argumen tipe dari penerima dan argumen. Jika inferensi gagal, ekstensi tersebut tidak dipertimbangkan.

using System;
using System.Collections.Generic;

public static class SeqExt
{
    public static T FirstItem<T>(this IEnumerable<T> source)
    {
        foreach (var item in source) return item;
        throw new InvalidOperationException("empty");
    }
}

public class Program
{
    public static void Main()
    {
        var nums = new List<int> { 5, 6, 7 };
        // T inferred as int from the List<int> receiver
        Console.WriteLine(nums.FirstItem());
    }
}

Direktif global using dan Impor Implisit

C# modern dapat mendeklarasikan direktif global using sehingga sebuah ruang nama berada dalam cakupan di seluruh proyek. Dengan begitu, pustaka ekstensi bersama tersedia di mana saja tanpa mengulangi impor.

using System;

// In a real project a separate file might say: global using MyHelpers;
namespace MyHelpers
{
    public static class IntExt { public static int Twice(this int n) => n * 2; }
}

public class Program
{
    public static void Main()
    {
        // Works here because MyHelpers is referenced explicitly
        Console.WriteLine(MyHelpers.IntExt.Twice(8));
    }
}

Saat Tipe Penerima Berpengaruh

Resolusi bergantung pada tipe statis penerima, bukan tipe saat berjalan. Ekstensi yang dideklarasikan untuk tipe dasar tetap berlaku saat variabel menyimpan instans turunan, kecuali ada ekstensi yang lebih spesifik dalam cakupan.

using System;

public class Animal { }
public class Cat : Animal { }

public static class AnimalExt
{
    public static string Kind(this Animal a) => "animal";
}

public class Program
{
    public static void Main()
    {
        Animal a = new Cat();
        // Chosen by static type Animal
        Console.WriteLine(a.Kind());
    }
}

Model Mental untuk Resolusi

Anggap urutannya sebagai berikut: (1) metode instans, lalu (2) metode ekstensi dari ruang nama yang diimpor, dimulai dari yang terdekat, kemudian (3) resolusi kelebihan beban di antara kandidat. Mengetahui urutan ini menjelaskan hampir semua hasil yang mengejutkan.

using System;

public static class Ext
{
    public static string Wrap(this string s) => "<" + s + ">";
}

public class Program
{
    public static void Main()
    {
        // No instance Wrap exists, so the extension is used
        Console.WriteLine("node".Wrap());
    }
}

Coba Sendiri

Tentukan ekstensi dalam sebuah ruang nama, impor ruang nama tersebut, lalu panggil ekstensi itu. Setelah itu, panggil metode yang sama secara eksplisit sebagai metode statis untuk melihat bahwa kedua cara tersebut berfungsi.

using System;
using Text.Helpers;

namespace Text.Helpers
{
    public static class StringExtensions
    {
        public static int Vowels(this string s)
        {
            int count = 0;
            foreach (var c in s.ToLower())
                if ("aeiou".IndexOf(c) >= 0) count++;
            return count;
        }
    }
}

public class Program
{
    public static void Main()
    {
        Console.WriteLine("education".Vowels());
        Console.WriteLine(Text.Helpers.StringExtensions.Vowels("education"));
    }
}

Pemeriksaan Singkat

Pertimbangkan hal-hal yang membuat metode ekstensi terlihat.

Ringkasan

Resolusi metode ekstensi mengikuti urutan yang jelas.

  • Metode instans dicoba terlebih dahulu; ekstensi hanya mengisi kekosongan.
  • Ekstensi hanya terlihat jika ruang namanya berada dalam cakupan melalui using atau global using.
  • Ruang nama yang lebih dekat diprioritaskan; hasil seri yang tidak terselesaikan menjadi galat kompilasi.
  • Anda selalu dapat memanggil metode statis secara eksplisit untuk menghilangkan ambiguitas.
  • Resolusi menggunakan tipe statis penerima.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Resolusi Metode Ekstensi” gratis?

Ya — teks lengkap “Resolusi Metode Ekstensi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C# Academy, upgrade ke CoddyKit PRO. Kursus C# Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Resolusi Metode Ekstensi”?

Pahami cara compiler menemukan ekstensi. Kamu berlatih C# Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai C# Academy?

Tidak diperlukan pengalaman sebelumnya. C# Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Resolusi Metode Ekstensi” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran C# Academy ini?

Ya. Setiap pelajaran C# Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mendefinisikan Metode Ekstensi
  2. Memperluas Antarmuka dan Generik
  3. Resolusi Metode Ekstensi
  4. Merancang Ekstensi yang Baik
← Kembali ke C# Academy