Arşiv

yılı için arşiv

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ş
	}
}

C# SortedSet sınıfı

31 Ekim 2010 1 yorum

SortedSet sınıfı, .Net Framework 4.0 ile birlikte gelen en yeni sınıflardan biridir ve listesine eklenen elemanları sıralı bir şekilde tutar.

Bir örnek ile göstermek gerekirse;

public static void Main(string[] args)
{
	var SiraliListe = new SortedSet<string>();

	SiraliListe.Add("Engin");
	SiraliListe.Add("Ahmet");
	SiraliListe.Add("Mehmet");
	SiraliListe.Add("Ayşe");
	SiraliListe.Add("Fatma");

	foreach (string s in SiraliListe)
	{
		Console.WriteLine(s);
	}

	Console.ReadLine();
}

kodunun çıktısı aşağıdaki gibi olacaktır;

Ahmet
Ayşe
Engin
Fatma
Mehmet
public static void Main(string[] args)
{
	var SiraliListe = new SortedSet<int>() { 2, 5, 4, 6, 9, 3, 2, 8, 10, 7, 1 };

	foreach (int Sayi in SiraliListe)
	{
		Console.WriteLine(Sayi);
	}

	Console.ReadLine();
}
Çıktı : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

Tüm koleksiyonlara uygulayabildiğimiz Reverse() methodu SortedSet sınıfında da kullanılabiliyor;

public static void Main(string[] args)
{
	var SiraliListe = new SortedSet<int>() { 2, 5, 4, 6, 9, 3, 2, 8, 10, 7, 1 };

	foreach (int Sayi in SiraliListe.Reverse())
	{
		Console.WriteLine(Sayi);
	}

	Console.ReadLine();
}
Çıktı : 10, 9, 8, 7, 6, 5, 4, 3, 2, 1

Clear() methodu, tüm elemanları silmeye yarıyor;

public static void Main(string[] args)
{
	var SiraliListe = new SortedSet() { 2, 5, 4, 6, 9, 3, 2, 8, 10, 7, 1 };

	SiraliListe.Clear();

	Console.ReadLine();
}

Min ve Max özellikleri sayesinde listedeki en küçük ve en büyük değerli elemanlara ulaşabiliriz;

public static void Main(string[] args)
{
	var SiraliListe = new SortedSet<int>() { 2, 5, 4, 6, 9, 3, 2, 8, 10, 7, 1 };

	Console.WriteLine("Min : {0}, Max : {1}", SiraliListe.Min, SiraliListe.Max);

	Console.ReadLine();
}
Çıktı : Min : 1, Max : 10

C# WMI Örnekler – 1

31 Ekim 2010 1 yorum

Bilgisayardaki Paylaşılan Dizinleri listelemek için; (Win32_Share sınıfını kullanır)

ManagementObjectSearcher mos = new ManagementObjectSearcher("select * from win32_share");
foreach (ManagementObject mo in mos.Get())
{
	Console.WriteLine("Dizin : {0}", mo["Name"]);
}

Bilgisayarda Elle Başlatılan ve Çalışan Servisleri listelemek için; (Win32_Service sınıfını kullanır)

ManagementObjectSearcher mos = new ManagementObjectSearcher("Select * from Win32_Service Where State='Running' AND StartMode='Manual'");
foreach (ManagementObject mo in mos.Get())
{
	Console.WriteLine("Servis : {0}", mo["Name"]);
}

Bilgisayarda o anda Çalışmakta olan Process‘leri listelemek için; (Win32_Process sınıfını kullanır)

ManagementObjectSearcher mos = new ManagementObjectSearcher("Select * from Win32_Process");
foreach (ManagementObject mo in mos.Get())
{
	Console.WriteLine("Process : {0}", mo["Name"]);
}

Bilgisayarda bulunan İşlemcileri (CPU) listelemek için; (Win32_Processor sınıfını kullanır)

ManagementObjectSearcher mos = new ManagementObjectSearcher("Select * from Win32_Processor");
foreach (ManagementObject mo in mos.Get())
{
	Console.WriteLine("Process : {0}", mo["Name"]);
}

Win32 sınıflarının tamamına ve özelliklerine MSDN‘deki Win32 Classes sayfasından ulaşabilirsiniz.

Bilgisayarın WIFI sinyal seviyesini göstermek için; (Technet‘teki makaleden alıntıdır.)

ManagementObjectSearcher mos = new ManagementObjectSearcher(@"root\WMI", "select * from MSNdis_80211_ReceivedSignalStrength");
foreach (ManagementObject mo in mos.Get())
{
	Console.WriteLine("", mo["Ndis80211ReceivedSignalStrength"]);
}

Notebook’ta Kalan Pil Süresini göstermek için; (SystemInformation sınıfını kullanır)

Console.WriteLine("Kalan pil yüzdesi : {0}", SystemInformation.PowerStatus.BatteryLifePercent);

Console.WriteLine("Kalan pil süresi : {0}", SystemInformation.PowerStatus.BatteryLifeRemaining);

For – ForEach – List.ForEach performans karşılaştırması

31 Ekim 2010 1 yorum

Bir dizinin tüm elemanları üzerinde bir aksiyon gerçekleştirmemiz gerektiğinde, sıklıkla şu üç yoldan birini kullanırız;

  • For döngüsü
  • ForEach Döngüsü
  • List generic sınıfının ForEach extension method’u

Şimdi basit bir örnek ile bu üç yöntemi karşılaştıralım (*);

(* Not : Karşılaştırmalar; Windows7 64bit kurulu, Core2Duo 3.0 GHz ve 4 GB Ram’li bilgisayarımda yapılmıştır. Sadece fikir verme amaçlıdır, farklı durumlarda faklı sonuçlar ile karşılaşılabilir.)

Öncelikle parametre olarak Generic List (List<T>) alan üç tane method yazalım;

private static long ToplamFor(List<int> Liste)
{
	long Sonuc = 0;
	int ListeAdet = Liste.Count;

	for (int iLoop = 0; iLoop < ListeAdet; iLoop++)
		Sonuc += Liste[iLoop];

	return Sonuc;
}

private static long ToplamForEach(List<int> Liste)
{
	long Sonuc = 0;

	foreach (int Rakam in Liste)
		Sonuc += Rakam;

	return Sonuc;
}

private static long ToplamForEachExtension(List<int> Liste)
{
	long Sonuc = 0;

	Liste.ForEach(Rakam => Sonuc += Rakam);

	return Sonuc;
}

Aynı testi 10 defa gerçekleştirip, ortalamasını alacak bir test fonksiyonu yazalım. Yazacağımız fonksiyonu test listesinde olacak eleman adedini parametre olarak alacak;

private static void Testler(int ListeElemanAdet)
{
	List<int> ForSureler = new List<int>();
	List<int> ForEachSureler = new List<int>();
	List<int> ForEachExtensionSureler = new List<int>();

	List<int> TestVerisi = Enumerable.Range(0, ListeElemanAdet).ToList();

	Stopwatch sw = new Stopwatch();

	for (int iLoop = 0; iLoop < 10; iLoop++)
	{
		sw.Restart();
		ToplamFor(TestVerisi);
		sw.Stop();
		ForSureler.Add(sw.ElapsedTicks);

		sw.Restart();
		ToplamForEach(TestVerisi);
		sw.Stop();
		ForEachSureler.Add(sw.ElapsedTicks);

		sw.Restart();
		ToplamForEachExtension(TestVerisi);
		sw.Stop();
		ForEachExtensionSureler.Add(sw.ElapsedTicks);
	}

	Console.WriteLine("For Döngüsü ({0} Eleman) : {1}", ListeElemanAdet, ForSureler.Average());

	Console.WriteLine("ForEach Döngüsü ({0} Eleman) : {1}", ListeElemanAdet, ForEachSureler.Average());

	Console.WriteLine("ForEach Extension ({0} Eleman) : {1}", ListeElemanAdet, ForEachExtensionSureler.Average());
}

Artık uygulamamızın test fonksiyonunu kullanacak son kod parçasını yazabiliriz;

public static void Main(string[] args)
{
	Console.WriteLine("Test Başladı");

	Testler(1000);
	Testler(5000);
	Testler(10000);
	Testler(50000);
	Testler(100000);
	Testler(500000);
	Testler(1000000);
	Testler(5000000);
	Testler(10000000);
	Testler(50000000);

	Console.WriteLine("Test Bitti");

	Console.ReadLine();
}

Bakalım yaptığımız testler nasıl sonuç vermiş;

For - ForEach - ForEach extension Performans Karşılaştırması / Ekran Görüntüsü

Sonuçlardan aşağıdaki tabloyu çıkarttım;

Test Verisi For ForEach ForEach Extension
1.000 71,1 121,5 79,7
5.000 34,3 92,2 55,6
10.000 70,0 185,1 110,4
50.000 349,3 918,4 568,3
100.000 715,2 1.902,7 1.159,0
500.000 3.583,3 9.379,3 5.600,0
1.000.000 7.260,4 18.877,9 11.242,8
5.000.000 37.927,2 96.096,9 57.845,4
10.000.000 74.553,5 192.621,6 115.559,6
50.000.000 371.698,1 956.394,4 572.776,7

İlk olarak 50.000 elemana kadar olan listeler için karşılaştırma yapalım;

For - ForEach - ForEach extension Performans Karşılaştırması / 50.000 elemana kadar inceleme

Son olarak 50.000.000 elemana kadar olan listeler için karşılaştırma yapalım;

For - ForEach - ForEach extension Performans Karşılaştırması / 50.000.000 elemana kadar inceleme

Bu kodda ne yanlış var? – 7

31 Ekim 2010 4 yorum

Aşağıdaki kod sayesinde ekrana, listedeki isimleri küçük harflerle yazdırmak istiyorsunuz.

using System;
using System.Collections.Generic;

public class EkranaYazdir
{
	public static void Main()
	{
		List<string> Kisiler = new List<string>();

		Kisiler.Add("AHMET");
		Kisiler.Add("MEHMET");
		Kisiler.Add("AYŞE");
		Kisiler.Add("FATMA");

		/// string elemanları küçük harfe çevir
		Kisiler.ForEach(
			delegate(string k)
			{
				k = k.ToLower();
			}
		);

		/// console'a yaz
		Kisiler.ForEach(
			delegate(string s)
			{
				Console.WriteLine(s);
			}
		);
	}
}

MSDN‘de List<T>.ForEach() sayfasında;

Orjinali; Performs the specified action on each element of the List.

Türkçesi; Listedeki her eleman için belirlenmiş action çalıştırır.

yazısını okudunuz, ve kodun doğru çalışmasını bekliyorsunuz.

Fakat istediğiniz gibi çalışmıyor, sizce problem nedir ve nasıl düzeltilebilir?

Dosya uzantısını uygulamanız ile ilişkilendirin

30 Eylül 2010 1 yorum

Bir windows uygulaması geliştirdiniz ve uygulamanız belli uzantıdaki dosyalar üzerinde işlemler gerçekleştiriyor (Görüntüleme, Kaydetme, vs.)

Eğer ilgili uzantıdaki dosyaya çift tıklandığı zaman uygulamanızın açılmasını ve dosya üzerinde işlem yapmasını istiyorsanız, öncelikle dosya uzantısı ve uygulamanızı registry üzerinden birbiri ile ilişkilendirmelisiniz.

Aşağıdaki örnek kod sayesinde, eng uzantılı dosyaların uygulamanız ile ilişkilendirilmesini ve dosya ikonlarının sizin belirlediğiniz (icon.ico) olarak gözükmesini sağlayabilirsiniz;

Registry.ClassesRoot.CreateSubKey(".eng").SetValue(null, "EnginDosyasi.eng");

RegistryKey rk = Registry.ClassesRoot.CreateSubKey("EnginDosyasi.eng");
rk.CreateSubKey("DefaultIcon").SetValue(null, Application.StartupPath + "\\icon.ico");
rk.CreateSubKey(@"shell\open\command").SetValue(null, "\"" + Application.ExecutablePath + "\" \"%1\"");

eng uzantılı bir dosyaya çift tıklandığında artık sizin uygulamanız açılacaktır.

Çift tıklandığı için uygulamanızı açtıran dosyaya, aşağıdaki kod satırı ile ulaşabilirsiniz;

public static void Main(string[] args)
{
	string Dosya = args[1];
}

Euler – 6

27 Eylül 2010 Yorum yapılmamış

Euler serisinin altıncı yazısında, Project Euler’in 6. sorusunu çözeceğiz;

Orjinal Soru; The sum of the squares of the first ten natural numbers is,
12 + 22 + … + 102 = 385

The square of the sum of the first ten natural numbers is,
(1 + 2 + … + 10)2 = 552 = 3025

Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 – 385 = 2640.

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

Türkçesi; İlk 10 sayının karelerinin toplamı,
12 + 22 + … + 102 = 385

İlk 10 sayının toplamlarının karesi,
(1 + 2 + … + 10)2 = 552 = 3025

İlk 10 sayı için toplamların karesi ile karelerin toplamı arasındaki fark; 3025 – 385 = 2640′tır.

İlk 100 sayının toplamların karesi ile karelerin toplamı arasındaki farkı bulunuz.

Önce siz çözmeyi deneyin, çözemezseniz Devamını oku…

Nullable Tipler

26 Eylül 2010 Yorum yapılmamış

Nullable tipler, ilgili tip‘in değer aralığına ve karakteristiğine sahip olmakla birlikte ek olarak null değer de içerebilen yapılardır.

Basit olarak, değişkenin değer içerip içermediği bilgisini saklar.

Nullable tipler, System.Nullable<T> türündedirler (T, değer tipi olmalıdır)

Unutmayın! Sadece değer tipleri (value type) nullable olabilir.

C# dili değer tipi listesi‘ne daha önce yazdığım makale veya MSDN üzerinden ulaşabilirsiniz.

C# dilinde, Nullable tipte değişkenler iki şekilde tanımlanabilir.

Birinci yöntemde, System.Nullable generic tipini ilgili değer tipi ile birlikte yazabiliriz;

System.Nullable<int> adet;
System.Nullable<bool> sonuclandi;

İkinci yöntem, daha çok kullanılır ve daha kısa yazım şekline sahiptir. İlgili değer tipinin yanına soruişareti (?) karakteri koyarak yazılır;

int? adet;
bool? sonuclandi;

Bir nullable değişken, tanımlandığı anda null değerini içermez, sizin null eşitlemesini yapmanız beklenir;

int? adet = null;

Nullable tipteki bir değişkene değer ataması yapmak, normal bir değişkene değer ataması yapmak ile aynıdır.

adet = 100;

Nullable bir değişkenin değer içerip içermediğini anlamanın iki yolu vardır.

Birinci yöntemde, değişkenin null olup/olmadığı kontrol edilebilir.

if (adet != null)
{
	/// değeri var
}

Eğer değişken null değilse, değer içeriyor demektir.

İkinci yöntemde, değişkenin System.Nullable tipinden gelen sadece-okunabilir (read-only) HasValue özelliği kontrol edilir.

if (adet.HasValue)
{
	/// değeri var
}

Eğer değişken değer içeriyorsa, değeri okumak için, değişkenin System.Nullable tipinden gelen Value özelliği kullanılır.

Eğer değer içermeyen nullable bir değişkenin Value özelliğinden değer okumaya çalışırsanız, System.InvalidOperationException istisnası fırlatılır.

using System;

class NullableTipTest
{
	public static void Main()
	{
		int? adet = null;

		if (adet.HasValue)
			Console.WriteLine("adet değeri: " + adet.Value);
		else
			Console.WriteLine("adet değeri yok.");

		adet = 10;

		if (adet.HasValue)
			Console.WriteLine("adet değeri: " + adet.Value);
		else
			Console.WriteLine("adet değeri yok.");
	}
}

Yukarıdaki kodun çıktısı şöyle olacaktır;

adet değeri yok.
adet değeri: 10

C# ile Windows Sistem Saatini Ayarlamak

25 Eylül 2010 2 yorum

Bazı windows uygulamalarının veya servislerinin Windows sistem saatini değiştirmesi gerekebilir.

C# ile geliştirdiğiniz uygulamalarda veya servislerde sistem saatini, basit bir Windows API çağrısı yaparak değiştirebilirsiniz.

Bu makale ile, SYSTEMTIME yapısını ve SetSystemTime fonksiyonunu nasıl tanımlayacağınızı ve kullanacağınızı anlatacağım.

SetSystemTime fonksiyonu bir Windows API çağrısıdır ve işletim sisteminin tarih/saat bilgisini değiştirmek için kullanılır.

kernel32.dll içerisinde tanımlanmış bu Windows API fonksiyonu, C# ile Platform Invocation Services (P/Invoke) çağrısı yapılarak kullanılabilir.

Öncelikle kod dosyamızın üstünde bulunan using kısmına System.Runtime.InteropServices namespace‘ini ekleyelim;

using System.Runtime.InteropServices;

Class seviyesinde aşağıdaki tanımlama ile SetSystemTime fonksiyonunun kernel32.dll içerisinde yer aldığını, parametrelerini ve geri dönüş tipini uygulamamıza bildirmiş oluyoruz;

[DllImport("kernel32.dll")]
public extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);

SetSystemTime fonksiyonu SYSTEMTIME tipinde bir parametre alıyor. SYSTEMTIME struct yapısını da uygulamamıza tanımlamamız gerekiyor;

[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
	public short Year;
	public short Month;
	public short DayOfWeek;
	public short Day;
	public short Hour;
	public short Minute;
	public short Second;
	public short Milliseconds;
}

Artık istediğimiz kod bloğunda ilgili fonksiyon çağrısını yaparak, sistem saatini ayarlayabiliriz;

SYSTEMTIME zaman = new SYSTEMTIME();
zaman.Day = 25;
zaman.Month = 9;
zaman.Year = 2010;
zaman.Hour = 14;
zaman.Minute = 45;
SetSystemTime(ref zaman);

SQL Agent Çalışma Durumu

21 Eylül 2010 Yorum yapılmamış

SQL Server servislerinden SQL Agent servisinin çalışıp çalışmadığını anlamamız gerektiği durumlarda msdb veritabanında tanımlı sp_help_job stored procedure‘ünü kullanabiliriz;

EXEC msdb..sp_help_job

Sorgu sonucunda dönen sonuç kümesinden, name alanında servisin ismi yer alırken, current_execution_status alanında servisin çalışma durumu yer alır.

Servisin çalışma durumunu gösteren birden fazla değer olabilir;

  • 1 : (Executing) Çalışıyor
  • 2 : (Waiting for thread) Çalışmaya devam ediyor
  • 3 : (Between retries) Tekrar deneniyor
  • 4 : (Idle) Boşta
  • 5 : (Suspended) Durdurulmuş
  • 7 : (Performing completion actions) Tamamlama görevi sürdürülüyor