Arşiv

Etiketlenen yazılar extension method

C# String Dizisini String Uzunluğuna Göre Sıralamak

19 Ağustos 2011 Yorum yapılmamış

Geliştirdiğimiz projelerde ekrana listeleyeceğimiz dizileri harf uzunluklarına göre sıralamak isteyebiliriz.

Bu makale ile, IEnumerable<string> tipinden değişkenlere bu özelliği nasıl ekleyeceğimizi göreceğiz.

Öncelikle Extension Method‘umuzu static bir sınıf içerisine (ExtensionManager) yazmamız lazım;

public static class ExtensionManager
{
	public static IEnumerable<string> Sirala(this IEnumerable<string> Liste)
	{
		string[] strArray = Liste.ToArray<string>();
		Array.Sort(strArray, new Comparison<string>(delegate(string Kelime1, string Kelime2)
		{
			if (Kelime1 == null && Kelime2 == null)
			{
				return 0;
			}
			else if (Kelime1 == null)
			{
				return -1;
			}
			else if (Kelime2 == null)
			{
				return 1;
			}
			else
			{
				if (Kelime1.Length < Kelime2.Length)
					return -1;
				else if (Kelime1.Length > Kelime2.Length)
					return 1;
				else
					return Kelime1.CompareTo(Kelime2);
			}
		}));

		return strArray;
	}
}

Yukarıdaki kod’da Array sınıfının static Sort method’unu çağırıyoruz. Karşılaştırma koşulunu, ikinci parametre’de delegate method olarak yazıyoruz.

Kullanımı;

var Rakamlar = new List { "12", "1", null, "2314", "55555", "123", "222" };

foreach (var Rakam in Rakamlar.Sirala())
{
	Console.WriteLine(Rakam);
}

Sonuç;

[null]
1
12
123
222
2314
55555

C# Liste’nin eleman içerdiğini kontrol etmek

30 Kasım 2010 1 yorum

Aşağıdaki kod parçasına, programlama üzerine yazılmış bir makaleyi okurken rastladım;

public void IsNullOrEmpty<T>(IEnumerable<T> koleksiyon)
{
	if (koleksiyon == null || koleksiyon.Count() == 0)
	{
		/// Koleksiyon'da hiç eleman yok
		/// Koleksiyon boş
	}
}

Yukarıdaki method IEnumerable generic tipinde parametre alıyor, null veya boş olup/olmadığını kontrol ediyor.

Karşılaştırmada kullanılan,

Liste.Count() == 0

kod parçası dikkatimi çekti.

Eğer IsNullOrEmpty fonksiyonuna parametre olarak ICollection<T> interface‘ini implemente etmeyen tipten bir değer gönderecek olursak (mesela LINQ sorgusu sonucu olarak IQueryable) Count method’u tüm liste üzerinde satır-satır ilerleyerek listedeki eleman adedini hesaplayacaktır.

Eğer fonksiyona parametre olarak IEnumerable interface‘ini implemente eden tipten bir değer gönderecek olursak, Count method’u, optimize edilmiş haliyle, sadece koleksiyonun Count özelliğini sorgulayacaktır.

Türkçe ifadesiyle; “Koleksiyonda eleman var mı?” sorusu yerine “Koleksiyon’da sıfır eleman mı var?” sorusunu sormuş oluyoruz.

Aslında çözüm basit, System.Linq namespace‘inde yeralan Any extension method‘unu kullanmamız gerekiyor;

public void Test<T>(IEnumerable<T> koleksiyon)
{
	if (koleksiyon == null || !koleksiyon.Any())
	{
		/// Koleksiyon'da hiç eleman yok
		/// Koleksiyon boş
	}
}

Bu yöntemin güzelliği, IEnumerable interface‘inin MoveNext methodunu sadece bir kere çağırması. Koleksiyonda bulunan eleman adedi ne olursa olsun, Any methodu sonucu çok hızlı birşekilde döndürecektir.

Hatta kendi extension method‘umuzu da Any methodunu kullanarak yazabiliriz;

public static bool IsNullOrEmpty<T>(this IEnumerable<T> koleksiyon)
{
	return koleksiyon == null || !koleksiyon.Any();
}

Artık extension method‘u da yazdığımıza göre, asıl method‘u iyileştirebiliriz;

public void Test<T>(IEnumerable<T> koleksiyon)
{
	if (koleksiyon.IsNullOrEmpty())
	{
		/// Koleksiyon'da hiç eleman yok
		/// Koleksiyon boş
	}
}

Dizide bir elemandan kaç adet olduğunu bulalım

20 Temmuz 2010 Yorum yapılmamış

Elimizdeki bir dizide, belli bir elemandan kaç adet olduğunu bulmamız gerekebilir.

Bunu yapmanın programatik olarak en kolay yolu LINQ sorgusu yazmaktır.

Örneğin aşağıdaki Extension Method, LINQ sorgusu ile aranan elemandan, ilgili listede kaç adet olduğu sonucunu döndürür;

public static int CountTimes< T >(this List< T > list, T item)
{
	return ((from t in list where t.Equals(item) select t).Count());
}

Örnek kullanım;

using System;
using System.Linq;
using System.Collections.Generic;

public static class Program
{
	static void Main(string[] args)
	{
		var list1 = new List< int >() { 1, 2, 3, 4, 5, 6, 7, 7, 8, 9 };
		var list2 = new List< string >() { "a", "b", "b", "b", "c", "d", "e", "f" };

		Console.WriteLine("Birinci listede 7, " + list1.CountTimes(7) + " adet var");
		Console.WriteLine("İkinci  listede b, " + list2.CountTimes("b") + " adet var");

		Console.ReadLine();
	}

	public static int CountTimes< T >(this List< T > list, T item)
	{
		return ((from t in list where t.Equals(item) select t).Count());
	}
}

Yukarıdaki örnek kodu çalıştırdığınızda, şöyle bir sonuç almanız lazım;

Birinci listede 7, 2 adet var
İkinci  listede b, 3 adet var

Ayın ilk ve son gününü bulmak için Extension Method

08 Temmuz 2010 Yorum yapılmamış

Özellikle raporlama uygulamalarında, aylık dönemlere ait sorgulama yapılırken ilgili ayın ilk ve son günlerinin bilinmesi gerekir.

C# uygulamamızda, yazacağımız basit iki tane extension method ile ayın ilk ve son günlerini bulan kodu basitleştirebiliriz.

public static class ExtensionMethods
{
	public static DateTime AyinIlkGunu(this DateTime dt)
	{
		return new DateTime(dt.Year, dt.Month, 1);
	}

	public static DateTime AyinSonGunu(this DateTime dt)
	{
		return dt.AyinIlkGunu().AddMonths(1).AddDays(-1);
	}
}

Extension Method‘ların kullanımı;

static void Main(string[] args)
{
	DateTime BuAy_BaslangicTarihi = DateTime.Now.AyinIlkGunu();
	DateTime BuAy_BitisTarihi = DateTime.Now.AyinSonGunu();

	DateTime GecenAy_BaslangicTarihi = DateTime.Now.AddMonths(-1).AyinIlkGunu();
	DateTime GecenAy_BitisTarihi = DateTime.Now.AddMonths(-1).AyinSonGunu();
}

Örnek kodun tamamı;

using System;

class Program
{
	static void Main(string[] args)
	{
		DateTime BuAy_BaslangicTarihi = DateTime.Now.AyinIlkGunu();
		DateTime BuAy_BitisTarihi = DateTime.Now.AyinSonGunu();

		DateTime GecenAy_BaslangicTarihi = DateTime.Now.AddMonths(-1).AyinIlkGunu();
		DateTime GecenAy_BitisTarihi = DateTime.Now.AddMonths(-1).AyinSonGunu();
  }
}

public static class ExtensionMethods
{
	public static DateTime AyinIlkGunu(this DateTime dt)
	{
		return new DateTime(dt.Year, dt.Month, 1);
	}

	public static DateTime AyinSonGunu(this DateTime dt)
	{
		return dt.AyinIlkGunu().AddMonths(1).AddDays(-1);
	}
}

FileStream sınıfına Kaydet() ExtensionMethod’u yazalım

01 Mart 2010 Yorum yapılmamış

FileStream sınıfına yazacağımız Save() method’u sayesinde, aşağıdaki kodu kolaylıkla yazabilir olacağız. Üstelik bir tane de overload yazarak, varolan dosyanın üstüne yazmasını engelleyip, yeni bir dosya adı oluşturup yazma işlemine devam ettirebileceğiz.

fs.Kaydet("c:\\dosya_adi.uzanti");

Eğer aynı kodu, ikinci bir boolean parametreye true değeri vererek çağırırsak, klasörde dosya_adi.uzanti dosyası varsa dosya_adi[1].uzanti dosyasına yazmayı deneyecek, eğer bu dosya da varsa, dosya_adi[2].uzanti dosyasına deneyecek, vs..

fs.Kaydet("c:\\dosya_adi.uzanti", true);

İşte kodumuz;

namespace ExtensionManager
{
	public static class Extensions
	{
		public static string Kaydet(this FileStream Dosya, string Dizin)
		{
			return Dosya.Kaydet(Dizin, false);
		}

		public static string Kaydet(this FileStream Dosya, string Dizin, bool UstuneYaz)
		{
			int DosyaSayac = 1;

			string _Dizin = Path.GetDirectoryName(Dizin);

			if (!Directory.Exists(_Dizin))
				Directory.CreateDirectory(_Dizin);

			int DosyaBoyu = Convert.ToInt32(Dosya.Length);
			string DosyaAdi = Path.GetFileName(Dosya.Name);

			Byte[] b = new Byte[DosyaBoyu];
			Dosya.Read(b, 0, DosyaBoyu);

			string root = Path.GetDirectoryName(Dizin) + "\\" + Path.GetFileNameWithoutExtension(Dizin);

			while (!UstuneYaz && File.Exists(Dizin))
				Dizin = root + "[" + DosyaSayac++.ToString() + "]" + Path.GetExtension(Dizin);

			File.WriteAllBytes(Dizin, b);

			return Path.GetFileName(Dizin);
		}
	}
}

Şubat 2010 Seminerleri / İleri Seviye C#

26 Şubat 2010 Yorum yapılmamış

BilgeAdam Kadıköy Şubesinde gerçekleştirdiğim Şubat Seminerlerinin İleri Seviye C# prezentasyonuna buradan erişebilirsiniz.

Bu seminerde değindiğim konular;

  • Access Modifiers
  • Anonymous Types
  • Anonymous Methods
  • Object Initializers
  • Rezerve Methodlar
  • Partial Class
  • Partial Methods
  • Null Coalescing Operatörü
  • Auto Implemented Properties
  • Obsolete Attribute
  • Extension Methods

Powerpoint Prezentasyonu

Birkaç Faydalı Extension Method

30 Ocak 2010 Yorum yapılmamış

C# 3.0 ile gelen Extension Method desteğini çok kullanışlı bulduğum için, kendi uygulamalarımda kullanmaya çalışıyorum. Bu yazımda faydalı bulduğum birkaç Extension Method‘u toplamaya çalıştım.

Metni Encrypt – Decrypt Eden Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static string Encrypt(this string stringToEncrypt, string key)
		{
			if (string.IsNullOrEmpty(stringToEncrypt))
				throw new ArgumentException("Boş metin şifrelenemez");
			if (string.IsNullOrEmpty(key))
				throw new ArgumentException("Şifreleme için anahtar vermelisiniz");

			CspParameters cspp = new CspParameters();
			cspp.KeyContainerName = key;

			RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspp);
			rsa.PersistKeyInCsp = true;

			byte[] bytes = rsa.Encrypt(UTF8Encoding.UTF8.GetBytes(stringToEncrypt), true);

			return BitConverter.ToString(bytes);
		}

		public static string Decrypt(this string stringToDecrypt, string key)
		{
			if (string.IsNullOrEmpty(stringToDecrypt))
				throw new ArgumentException("Beş metnin şifresi çözülemez");
			if (string.IsNullOrEmpty(key))
				throw new ArgumentException("Şifre çözme için anahtar vermelisiniz");
			string result = null;
			try
			{
				CspParameters cspp = new CspParameters();
				cspp.KeyContainerName = key;

				RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspp);
				rsa.PersistKeyInCsp = true;

				string[] decryptArray = stringToDecrypt.Split("-");
				byte[] decryptByteArray = Array.ConvertAll<string, byte>(decryptArray, (s => Convert.ToByte(byte.Parse(s, NumberStyles.HexNumber))));
				byte[] bytes = rsa.Decrypt(decryptByteArray, true);

				result = UTF8Encoding.UTF8.GetString(bytes);
			}
			catch()
			{
			}
			return result;
		}
	}
}

Örnek kullanım;

string metin = "My Secret";
string sifrelenmis = metin.Encrypt("sifreleyici");
string sifresicozulmus = sifrelenmis.Decrypt("sifreleyici");

Listeler üzerinde Foreach Yapan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static void ForEach<T>(this IEnumerable<T> kaynak, Action<T> islem)
		{
			foreach (var item in kaynak)
				islem(item);
		}
	}
}

Örnek kullanım;

List<string> isimler = new List<string> { "engin", "polat", "ahmet", "mehmet", "murat" };
isimler.ForEach(isim => MessageBox.Show(isim));

İnternet Adresi Doğrulayan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static bool IsValidUrl(this string text)
		{
			Regex r = new Regex(@"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?");
			return r.IsMatch(text);
		}
	}
}

Örnek kullanım;

string Adres = "http://www.enginpolat.com";
bool AdresDogru = Adres.IsValidUrl();

Email Adresi Doğrulayan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static bool IsValidEmail(this string text)
		{
			Regex r = new Regex(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");
			return r.IsMatch(text);
		}
	}
}

Örnek kullanım;

string Adres = "test@test.com";
bool AdresDogru = Adres.IsValidEmail();

Klasör Oluşturan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static void CreateDirectory(this DirectoryInfo dirInfo)
		{
			if (dirInfo.Parent != null)
				CreateDirectory(dirInfo.Parent);
			if (!dirInfo.Exists)
				dirInfo.Create();
		}
	}
}

Örnek kullanım;

var dir = new DirectoryInfo(@"C:\temp\bir\iki\uc");
dir.CreateDirectory();

Tarihin Haftasonuna Geldiğini Doğrulayan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static bool IsWeekend(this DateTime value)
		{
			return (value.DayOfWeek == DayOfWeek.Sunday || value.DayOfWeek == DayOfWeek.Saturday);
		}
	}
}

Örnek kullanım;

for (DateTime date = BaslangicTarih; date <= BitisTarih; date = date.AddDays(1))
{
	if (date.IsWeekend())
		continue;
	/// Tatil değil, yapılacak işler yapılır.
}

Object türünden JSON’a, JSON’dan Object Türüne Çeviren Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static string ToJson(this object obj)
		{
			JavaScriptSerializer serializer = new JavaScriptSerializer();
			return serializer.Serialize(obj);
		}

		public static T FromJson<T>(this object obj)
		{
			JavaScriptSerializer serializer = new JavaScriptSerializer();
			return serializer.Deserialize<T>(obj as string);
		}
	}
}

Örnek kullanım;

Personel Engin = new Personel("Engin Polat", 5000);
string json = Engin.ToJson();
Engin = null;
Engin = s.FromJson<Personel>();

Tarihten Yaş Hesaplayan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static int Age(this DateTime tarih)
		{
			DateTime now = DateTime.Now;
			int yas = now.Year - tarih.Year;
			if (now < tarih.AddYears(yas))
				yas--;
			return yas;
		}
	}
}

Örnek kullanım;

DateTime AhmetDogumGunu = new DateTime(1979, 05, 07);
int Yas = AhmetDogumGunu.Age();

Ayın İlk Gününü – Ayın Son Gününü Bulan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static DateTime FirstDayOfMonth(this DateTime date)
		{
			return new DateTime(date.Year, date.Month, 1);
		}

		public static DateTime LastDayOfMonth(this DateTime date)
		{
			return new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(1).AddDays(-1);
		}
	}
}

Örnek kullanım;

DateTime Simdi = DateTime.Now;
MessageBox.Show("Ayın ilk günü: " + Simdi.FirstDayOfMonth().ToShortDateString());
MessageBox.Show("Ayın son günü: " + Simdi.LastDayOfMonth().ToShortDateString());

Dosyanın MD5 Değerini Hesaplayan Extension Method

namespace ExtensionManager
{
	public static class Extensions
	{
		public static string GetMD5(this string filename)
		{
			string result = string.Empty;

			try
			{
				MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider();
				FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
				byte[] arrByteHashValue = md5Provider.ComputeHash(fileStream);
				fileStream.Close();

				string hashData = BitConverter.ToString(arrByteHashValue).Replace("-", "");
				result = hashData;
			}
			catch()
			{
			}
			return result.ToLower();
		}
	}
}

Örnek kullanım;

string Dosya = @"C:\Temp\DosyaAdi.txt";
MessageBox.Show(Dosya + " dosyasının MD5 değeri: " + Dosya.GetMD5());

C# String’i Title Case’e (Kelimelerin Baş Harfleri Büyük Gerisi Küçük) Çevirme

25 Ocak 2010 8 yorum

.Net Framework içerisinde string.ToUpper() ve string.ToLower() fonksiyonlarını kullanarak string değişkenin içeriğini BÜYÜK ve küçük harfe çevirebiliyoruz.

Metni Upper Case (Tümü Büyük Harfler) ve Lower Case (Tümü Küçük Harfler) formatlamak haricinde Title Case (Kelimelerin Baş Harfleri Büyük Gerisi Küçük) çevirmek yaygın kullanılan başka bir formattır.

string sınıfına bir Extension Method yazarak bu özelliğe sahip olmasını sağlayabiliriz. Extension Method‘u yazarken bilmemiz gereken ilk şey, ToTitleCase() method’unun TextInfo sınıfında yer aldığıdır. TextInfo sınıfına CultureInfo sınıfının CurrentCulture özelliğinden ulaşabiliriz.

public static class ExtensionManager
{
	public static string ToTitleCase(this string Text)
	{
		return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Text);
	}
}

Artık projemiz içerisinde herhangi bir yerde string değişkenimizin ToTitleCase() method’unu kullanabiliriz.

private void frmMain_Load(object sender, EventArgs e)
{
	string AdSoyad = "engin polat".ToTitleCase();
}

Yukarıdaki kod parçası çalıştığı zaman, AdSoyad değişkeninin içeriği Engin Polat olacaktır.

Not : CultureInfo sınıfının CurrentCulture özelliğinden TextInfo sınıfının özelliklerine eriştiğimiz için, bilgisayarınızda kullandığınız dile göre sonuç farklılık gösterebilir.

C# ile isNumeric() fonksiyonu yazalım

04 Ocak 2010 1 yorum

VB.NET programcılarının kullanabildiği, ama C#‘ta bulunmayan isNumeric() fonksiyonunu kendimiz yazacağız;

public static class ExtensionManager
{
	public static bool isNumeric(this string value)
	{
		double oReturn = 0;
		return double.TryParse(value, out oReturn);
	}
}

Artık C# kodumuzun herhangi bir yerinde

string Deger = "5";
bool Rakamsal = isNumeric(Deger);

veya

string Deger = "5";
bool Rakamsal = Deger.isNumeric();

kullanabiliriz.