C# Uzantı Metotları ve Yöntemleri Anlamak
C# programlamada, metodlar yeniden kullanılabilir kod kapsülleri oluşturarak ve belirli görevleri yerine getirerek temel yapı taşlarını oluşturur. Bunlar, parametre kabul edebilir, değer döndürebilir ve değişken girdileri işlemek için aşırı yüklenebilir. Daha ileri bir kavram olarak uzantı metodları, geliştiricilerin kontrol etmedikleri türlere bile işlevsellik eklemelerini sağlar.
Tim Corey'nin 'C#'ta Uzantı Metotları Nasıl Oluşturulur' videosu mükemmel bir kaynaktır. Bu kılavuzda Tim'in kapsadığı birkaç konuyu inceleyeceğiz:
- Yöntemleri Tanımlama ve Çağırma
- Yöntem Parametreleri ve Argümanları
- Yöntemin Geri Dönüş Değerleri
- Yöntem Aşırı Yükleme
- Uzantı Yöntemleri Uygulama
Yöntemleri Tanımlama ve Çağırma
Örnek Yöntemler Tanımlandı
C#'ta bir yöntem bir sınıf içinde tanımlanır. Yöntem tanımı için genel sözdizimi erişim belirtecini, dönüş türünü, yöntem adını ve parametreleri içerir.
public class SampleClass
{
public void SampleMethod()
{
// Method implementation
}
}public class SampleClass
{
public void SampleMethod()
{
// Method implementation
}
}Tim Corey'nin 4:05'teki örneğinde, bir uzantı yöntemi oluşturmak için statik bir sınıf içinde bir yöntem tanımlar. Tanımlanan yöntem PrintToConsole. Tanım, pratik bir örnekle bir yöntemin nasıl tanımlanacağını açıkça anlatan tüm genel sözdizimini içerir:
public static class Extensions
{
public static void PrintToConsole(this string message)
{
Console.WriteLine(message);
}
}public static class Extensions
{
public static void PrintToConsole(this string message)
{
Console.WriteLine(message);
}
}Bir Yöntemi Çağırma
'Yöntem çağrısı', programın kodda başka bir yerde tanımlanmış belirli bir yöntemi yürütmesini söyler ve önceden belirlenmiş bir eylemi gerçekleştirir. Yöntemler sınıf örneği kullanılarak veya doğrudan statik yöntemlerse çağrılır. Uzantı yöntemlerinde, uzattıkları türün bir parçasıymış gibi görünürler. Tim, 6:18'deki videoda, ilkel bir veri türüyle tanımlanmış yöntemler gibi bir uzantı yönteminin nasıl çağrılacağını gösterir.
string demo = "This is a demo";
demo.PrintToConsole(); // Extension method callstring demo = "This is a demo";
demo.PrintToConsole(); // Extension method callYöntem Parametreleri ve Argümanları
Parametreler
Parametreler, yöntem tanımında belirtilir ve yönteme geçirilen değerler için birer yer tutucu olarak işlev görür. WriteLine yöntemi çağrıldığında, message parametre olduğu yerde bunu burada görebilirsiniz.
public void DisplayMessage(string message)
{
Console.WriteLine(message);
}public void DisplayMessage(string message)
{
Console.WriteLine(message);
}Yine, Tim Corey'nin 4:05'te verdiği genişletme yöntemi örneğinde, message parametredir:
public static void PrintToConsole(this string message)
{
Console.WriteLine(message);
}public static void PrintToConsole(this string message)
{
Console.WriteLine(message);
}Argümanlar
Argümanlar, yöntem çağrıldığında yönteme geçirilen gerçek değerlerdir.
DisplayMessage("Hello, World!"); // "Hello, World!" is the argumentDisplayMessage("Hello, World!"); // "Hello, World!" is the argumentTim Corey 6:20'de yöntemi string türü ile nokta sözdizimini kullanarak çağırdığında, string değeri aslında PrintToConsole yöntemine değer olarak aktarılır:
string demo = "This is a demo";
demo.PrintToConsole(); // "This is a demo" is the argumentstring demo = "This is a demo";
demo.PrintToConsole(); // "This is a demo" is the argumentYöntemin Geri Dönüş Değerleri
Yöntemler, return ifadesi kullanarak değer döndürebilirler. Return türü, yöntem imzasında belirtilir.
public int Add(int a, int b)
{
return a + b;
}public int Add(int a, int b)
{
return a + b;
}Tim Corey'nin videosundaki uzantı yöntemi herhangi bir değer döndürmüyor (void dönüş türü), ancak geri dönüş değeri ile uzantı yöntemleri oluşturabilirsiniz. Tim'in örneğinde dönüş türü void, yani yöntem herhangi bir değer döndürmez. Aşağıdaki örnek nasıl değer döndürüleceğini gösterir:
public static int WordCount(this string str)
{
return str.Split(' ').Length;
}public static int WordCount(this string str)
{
return str.Split(' ').Length;
}Yöntem Aşırı Yükleme (11:15)
Yöntem aşırı yükleme, aynı ada sahip ancak farklı parametrelere sahip birden fazla yöntem oluşturmanıza olanak tanır. Bu, esnek ve sezgisel API'ler oluşturmak için faydalı olabilir.
public void Display(string message)
{
Console.WriteLine(message);
}
public void Display(int number)
{
Console.WriteLine(number);
}public void Display(string message)
{
Console.WriteLine(message);
}
public void Display(int number)
{
Console.WriteLine(number);
}Tim Corey, 11:24'te farklı günlükleme senaryoları için birden fazla yöntem oluşturmanın bir örneği olarak görülebilecek yöntemin aşırı yüklenmesi hakkında kısaca bilgi verir. Günlük yöntemi iki kez vardır, biri tek parametreli ve diğeri iki parametreli. 11:39'da ikinci günlük yöntemi, günlük yönteminin aşırı yüklenmiş bir versiyonudur ve aynı ad altında çeşitli işlevler kazandırır.
C#'ta Uzantı Yöntemlerini Uygulama
Uzantı Yöntemleri Nedir? (3:13)
Uzantı yöntemleri, varolan türlere onları değiştirip yeniden derlemeye gerek kalmadan yeni yöntemler eklemenize olanak tanır. Örnek yöntemlermiş gibi çağrılsalar da uzantı yöntemleri statik olarak tanımlanır.
Uzantı Yöntemi Yaratma
Önceki bölümde, 'Yöntemleri Tanımlama ve Çağırma', Tim Corey'nin ayrı bir statik sınıfta bir uzantı yöntemi oluşturduğunu ve uzantı yöntemi olarak kullanılacak statik yöntemi tanımladığını vurguladık. Burada Tim Corey'nin vurguladığı bazı önemli noktalar şunlardır:
- Ayrı bir public static sınıf tanımladığınızdan emin olun veya Tim'in dediği gibi, "sınıfı statik olarak işaretleyin aksi halde çalışmayacaktır."
- Daha fazla uzantı yöntemi oluştururken, onları türüne göre gruplayın (3:43)
- İlk parametresi
thisanahtar kelimesiyle öneklenmiş ve genişletilecek türü belirten statik bir yöntem tanımlayın (4:58)
public static class Extensions
{
public static void PrintToConsole(this string message)
{
Console.WriteLine(message);
}
}public static class Extensions
{
public static void PrintToConsole(this string message)
{
Console.WriteLine(message);
}
}Uzantı Yöntemi Çağrısı (6:18)
Sonra, Tim, bu string değişkende bir uzantı yönteminin nasıl çağrılacağını gösterir:
demo.PrintToConsole();demo.PrintToConsole();demo girdiğinizde ve Print yazmaya başladığınızda, IntelliSense PrintToConsole yöntemini önerir. Bu, string türüne eklenen yeni yöntemdir.
Yöntem Çağrısının Çalışma Şekli (6:30)
Tim, demo.PrintToConsole() yöntemini neden çağırabileceğinizi açıklar:
- Demo Bir String Türüdür:
demodeğişkenistringtüründedir. - Genişletilmiş String Türü:
stringtürü yeni yöntemPrintToConsoleile genişletilmiştir.
Parametreyi Anlamak (6:41)
PrintToConsole yöntemine hiçbir parametre aktarılmıyor gibi görünmesine rağmen, Tim dolaylı parametre aktarımına dikkat çeker - demo stringi genişletme yöntemine ilk parametre olarak aktarılır.
Tim, uzantı yöntemlerinin çağrı sonucunda tanımlarında bir parametre daha az olmasına dikkat çekiyor. Bunun nedeni, ilk parametrenin (uzatılan tür) örtük olmasıdır.
Uzantı Yöntemi İmzası
Burada, this string message yöntemin string türünü genişlettiği anlamına gelir ve message dolaylı parametredir:
public static void PrintToConsole(this string message)public static void PrintToConsole(this string message)Kodu Çalıştırma (7:08)
Son olarak, PrintToConsole yöntemi çağrıldığında, stringi konsola yazdırır:
Console.WriteLine(message);Console.WriteLine(message);Bu nedenle, demo.PrintToConsole() çağrısı "Bu bir demodur" çıktısını konsola yazdırır.
Üçüncü Taraf Sınıfları İçin Uzantı Yöntemlerini Kullanma
Üçüncü Taraf Sınıfları Genişletme (10:59)
Tim Corey, uzantı yöntemlerinin değiştiremeyeceğiniz üçüncü taraf sınıfları bile genişletebileceğini açıklar. Örneğin, 11:09'daki SimpleLogger sınıfına bir göz atalım.
Burada, Tim, mesajları konsola kaydeden varsayımsal üçüncü taraf sınıfı SimpleLogger kullanır (11:09). Sınıfın iki yöntemi vardır:
public class SimpleLogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
public void Log(string message, string messageType)
{
Console.WriteLine($"{messageType}: {message}");
}
}public class SimpleLogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
public void Log(string message, string messageType)
{
Console.WriteLine($"{messageType}: {message}");
}
}Bu yöntemler ideal değildir çünkü mesaj türü basit bir string'tir ve bu da tutarsızlıklara yol açabilir. Tim, sınıfı iyileştirmek için uzantı yöntemleri oluşturmayı öneriyor.
Tutarlı Mesaj Türlerini Uygulama
Uzantı yöntemleri kullanarak her zaman aynı mesaj türlerini ve biçimlendirmesini kullanarak kodunuzda tutarlılık sağlarsınız. Burada, (12:40)'ta, Tim bir statik sınıf ExtendSimpleLogger oluşturur:
public static class ExtendSimpleLogger
{
public static void LogError(this SimpleLogger logger, string message)
{
logger.Log(message, "Error");
}
public static void LogWarning(this SimpleLogger logger, string message)
{
logger.Log(message, "Warning");
}
}public static class ExtendSimpleLogger
{
public static void LogError(this SimpleLogger logger, string message)
{
logger.Log(message, "Error");
}
public static void LogWarning(this SimpleLogger logger, string message)
{
logger.Log(message, "Warning");
}
}Çağrıları Daha Tutarlı Yapma
Bunu elinde bulundurarak, (14:02) artık bir SimpleLogger örneği üzerinde genişletme yöntemlerini çağırabilir:
SimpleLogger logger = new SimpleLogger();
logger.LogError("This is an error");
logger.LogWarning("This is a warning");SimpleLogger logger = new SimpleLogger();
logger.LogError("This is an error");
logger.LogWarning("This is a warning");Bu, mesaj türlerinin her zaman 'Hata' ve 'Uyarı' olmasını sağlar.
Çıkış Biçimlendirmesini Geliştirme (14:35)
Tim, hata mesajları için konsol metin rengini ayarlamak için işlevsellik ekleyerek dikkat çekmelerini sağlıyor:
public static void LogError(this SimpleLogger logger, string message)
{
var defaultColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
logger.Log(message, "Error");
Console.ForegroundColor = defaultColor;
}public static void LogError(this SimpleLogger logger, string message)
{
var defaultColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
logger.Log(message, "Error");
Console.ForegroundColor = defaultColor;
}Doğrudan Yöntem Çağrıları ile Karşılaştırma (17:21)
Tim bu yaklaşımı, orijinal Log yöntemlerini doğrudan çağırmakla karşılaştırır, bu da tutarsızlıklara yol açabilir:
logger.Log("Test error", "Error");
logger.Log("Another error", "ERROR");logger.Log("Test error", "Error");
logger.Log("Another error", "ERROR");Bu yaklaşım yazım hatalarına ve tutarsız biçimlendirmeye yatkındır.
Uzantı Yöntemleri Zincirleme (18:13)
Tim, uzantı yöntemlerinin okunabilirliği artırmak için nasıl zincirleneceğini gösterir:
public static void LogInfo(this SimpleLogger logger, string message)
{
logger.Log(message, "Info");
}
public static void SaveToDatabase(this SimpleLogger logger)
{
// Simulate saving to a database
}public static void LogInfo(this SimpleLogger logger, string message)
{
logger.Log(message, "Info");
}
public static void SaveToDatabase(this SimpleLogger logger)
{
// Simulate saving to a database
}Şimdi, bu yöntemleri zincirleyebilirsiniz:
logger.LogInfo("Information").SaveToDatabase();logger.LogInfo("Information").SaveToDatabase();Bu, iç içe geçmiş yöntem çağrılarına kıyasla kodun daha okunabilir ve sezgisel olmasını sağlar:
SaveToDatabase(LogInfo(logger, "Information"));SaveToDatabase(LogInfo(logger, "Information"));Nokta notasyonu ve zincirleme kullanarak, kodun amacı daha belirgin ve daha az karmaşıktır.
Sahip Olmadığınız Şeyleri Genişletmek
20:13'te, Tim Corey, uzantı yöntemlerinin sahip olmadığınız sınıflara, örneğin üçüncü taraf kütüphanelerine işlevsellik eklemek için ideal olduğunu açıklar. Bu, orijinal kodu değiştirmeden geliştirmelere izin verir.
Bağımlılıklardan Kaçınmak
Corey ayrıca uzantı yöntemlerinin doğrudan bir sınıfa bağlamadan bağımlılıkları tanıtmak için kullanılmasına dikkat çeker. Örneğin, veritabanı kaydetme işlevini, veritabanı mantığını içermeden bir Person sınıfına eklemek.
Ara Yüzleri Genişletmek
Uzantı yöntemleri, 21:30'dan itibaren açıklandığı gibi, ara yüzlere de uygulanabilir ve bu da ara yüzü gerçekleştiren birden fazla sınıfın aynı işlevselliği paylaşmasını sağlar. Bu, kodun tekrar kullanılmasını ve basitleştirilmesini teşvik eder.
Uzantı Yöntemlerini Kullanmayacağınız Durumlar
Tim Corey 23:03'te, aşırı yüklenme olmaması için ilkel veya Microsoft tarafından sağlanan türlerle uzantı yöntemlerinin fazla kullanılmamasını öneriyor. Onları yalnızca net fayda sağladıklarında ve dikkatli bir şekilde kullanın.
Açık/Kapalı İlkesi
24:54-25:40 arasındaki bölümde Tim, mevcut, kararlı kodu değiştirmeden yeni işlevsellik eklemek için genişletme yöntemleri kullanarak açık/kapalı ilkesine uyulması gerektiğini vurguluyor. Bu, hata riskini azaltır.
Using Deyimleri için En İyi Uygulamalar
Genişletme yöntemlerini mantıksal olarak gruplandırarak düzenleyin ve isimlendirme çatışmalarını önlemek ve daha kolay bakım ve hata ayıklama için ayrı ad alanlarına yerleştirin.
Sonuç
Ve işte oradasınız—artık yöntem tanımlama ve çağırma, parametreleri ve dönüş değerlerini ele alma ve yöntem aşırı yüklemelerinden yararlanma temellerini anlıyorsunuz. Bununla birlikte, C# dilinde sağlam ve esnek uygulamalar geliştirebilirsiniz.
Tim Corey'nin açıkladığı gibi genişletme yöntemleri, mevcut türleri geliştirmenin ve kodunuzu daha okunabilir ve bakım yapılabilir hale getirmenin güçlü bir yolunu sunar. Daha ayrıntılı bilgiler ve pratik örnekler için, Tim Corey'nin C# Dilinde Genişletme Yöntemleri Nasıl Oluşturulur başlıklı tam videosunu izleyebilirsiniz.

