Arşiv

Etiketlenen yazılar struct

Bu kodda ne yanlış var? – 8

13 Haziran 2011 8 yorum

Çalıştığımız proje’de, aşağıda tanımı verilmiş struct‘tan 1000 tane üretip geri döndüren bir fonksiyon yazmamız gerekiyor;

struct Boyut
{
	public int Genislik;
	public int Yukseklik;
}

Proje Liderine yazdığımız kodu gösteriyoruz. Kod çalışırken hiçbir hata üretmemesine rağmen, kodu değiştirmemizi istiyor.

private Boyut[] BoyutlarListesi()
{
	Boyut[] boyutlar = new Boyut[1000];

	for (int iLoop = 0; iLoop < boyutlar.Length; iLoop++)
	{
		boyutlar[iLoop] = new Boyut();
	}

    return boyutlar;
}

Sizce neden böyle bir istekte bulunmuş olabilir?

İpucu : Proje Lideri performans takıntısı olan eski bir programcı

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);

C# Windows’un Boş Zamanını (Idle Time) Bulmak

30 Temmuz 2010 Yorum yapılmamış

Yazdığınız bir uygulamanın vakit alıcı bazı işlerini, Windows’un kullanılmadığı zamanlarda gerçekleştirmek isteyebilirsiniz.

Yapmamız gereken, uygulamamızın, Windows’un kullanılmadığı zamanı anlayabileceği ve sayabileceği bir yönteme sahip olmasını sağlamak.

Böylece Windows belirli bir süre boyunca kullanılmadığında, uygulamamızın çeşitli görevleri başlatmasını sağlayabiliriz.

Windows’un kullanılmadığı süreyi ölçmek için, öncelikle son kullanıldığı zamanı bulmamız gerekmektedir.

İlk olarak, kodumuzun using kısmına System , System.Runtime.InteropServices ve System.Timers namespace‘lerini ekleyelim.

System.Runtime.InteropServices namespace’i Windows API‘lerini uygulamamıza eklememize yarayan sınıfları barındırmaktadır.

DllImport sınıfını kullanarak, user32.dll Windows API‘sinde yeralan GetLastInputInfo methodunu uygulamamıza ekleyebiliriz.

GetLastInputInfo method’u sayesinde ihtiyacımız olan, Windows’un son kullanılma zamanını alabileceğiz.

[DllImport("user32.dll")]
static extern bool GetLastInputInfo(ref LastInputInfo plii);

Toplam Kullanılma Zamanından, Son Kullanılma Zamanını çıkarttığımızda, Windows’un Kullanılmadığı Boş Zamanı bulmuş olacağız.

TimeSpan.FromMilliseconds(Environment.TickCount - info.dwTime)

GetLastInputInfo method’u parametre olarak LastInputInfo tipinde bir struct istemektedir.

public struct LastInputInfo
{
	public uint cbSize;
	public uint dwTime;
}

Uygulamamızın başlangıcında bir Timer oluşturuyoruz ve Elapsed olayında, Windows’un kullanılmadığı süreyi ekrana yazdırıyoruz.

Örnek uygulamanın tüm kodu;

using System;
using System.Runtime.InteropServices;
using System.Timers;

public struct LastInputInfo
{
	public uint cbSize;
	public uint dwTime;
}

public class Program
{
	[DllImport("user32.dll")]
	static extern bool GetLastInputInfo(ref LastInputInfo plii);

	static LastInputInfo info = new LastInputInfo();

	public static TimeSpan GetInactiveTime()
	{
		if (GetLastInputInfo(ref info))
			return TimeSpan.FromMilliseconds(Environment.TickCount - info.dwTime);
		else
			return TimeSpan.Zero;
	}

	static void Main(string[] args)
	{
		info.cbSize = (uint)Marshal.SizeOf(info);

		Timer t = new Timer(1000);
		t.Start();
		t.Elapsed += delegate { Console.WriteLine(GetInactiveTime().ToString()); };

		Console.ReadLine();
	}
}

Kalıtımı engellemek (sealed anahtar kelimesi)

06 Mart 2010 Yorum yapılmamış

Yazdığınız bir sınıftan kalıtım yoluyla başka sınıflar üretilmesini engellemek istiyor olabilirsiniz.

Yapmanız gereken sınıfınızı sealed anahtar kelimesi ile “mühürlemek” olmalıdır. Böylece sınıfınızdan yeni sınıflar türetilemeyecektir.

sealed class AnaSinif
{
// Sınıf üyeleri
}

AnaSinif class‘ımız sealed olduğu için, yeni sınıf türetilirken base class olamayacaktır;

class TuretilmisSinif : AnaSinif
{
// Derleme zamanında hata oluşur (compile-time error)
}

Not : struct’lar her zaman sealed ile mühürlenmiş gibi davranırlar. struct’lar kalıtım (inheritance) desteklemez

Tüm sınıfın kalıtım yoluyla aktarılmasını engellemek yerine, tek bir method’un override edilmesini engellemek istiyor olabilirsiniz.

Bu durumda yapmanız gereken, sadece ilgili method‘u sealed ile “mühürlemek” olmalıdır;

class AnaSinif
{
	public virtual void Goster()
	{
	}
}

class TuretilmisSinif : AnaSinif
{
// Bu kodda problem yok
// AnaSinif'tan gelen Goster() method'unu override eder
// Aynı zamanda sealed ile "mühürler"
	public sealed override void Goster()
	{
	}
}

class TekrarTuretilmisSinif : TuretilmisSinif
{
// Bu kod derlenmez. Hata oluşur
// TuretilmisSinif class'ında Goster() method'u sealed anahtar kelimesi ile "mühürlenmişti"
	public override void Goster()
	{
	}
}

C# Rezerve Methodlar – Reserved Methods

21 Ocak 2010 Yorum yapılmamış

C# dilinin bazı yetenekleri, aslında uygulama geliştiricilerin göremedikleri method’lardan gelmektedir.

Eğer geliştirdiğiniz uygulamanın assembly’lerini ILDASM tool’u ile açıp incelerseniz, bu method çağrılarını görebilirsiniz.

Eğer bilerek veya yanlışlıkla bu method’lardan birisi ile aynı isme sahip method oluşturmaya çalışırsanız, derleme anında (compile-time) hata alırsınız.

Bu rezerve method isimlerini inceleyelim;

Özellikler (Properties) için Rezerve Methodlar;

Class veya Struct‘larınıza eklediğiniz özellikler, derleme zamanında

T add_{OzellikAdi}
void set_{OzellikAdi}(T value)

şablonunda iki method’a dönüştürülür. Class veya Struct‘ınıza bu şablona uyan method ekleyemezsiniz.

Indexer’lar için Rezerve Methodlar;

Indexer’larınız derleme zamanında

T get_Item(Parametre)
void set_Item(Parametre, T value)

şablonunda iki method’a dönüştürülür.

Yıkıcılar (Destructors) için Rezerve Methodlar;

Class veya Struct‘ınıza eklediğiniz Destructor kodu derleme zamanında

void Finalize()

method’una dönüştürülür. Class veya Struct‘ınıza Finalize() method’u eklemeye çalıştığınızda derleme zamanında uyarı alırsınız.

Olaylar (Events) için Rezerve Methodlar;

Olaylarınız için derleme zamanında kodunuza

void add_{EventAdi}(T callback)
void remove_{EventAdi}(T callback)

methodları eklenir.

C# Erişim Belirleyiciler – Access Modifiers

20 Ocak 2010 Yorum yapılmamış

Öncelikle erişim belirleyicilerin (access modifiers) nerelere uygulandığını bilmemiz lazım; C# projesinde tanımlanmış tüm varlıklara uygulanabilir, buna class, struct, function, method, property ve class seviyesindeki tüm değişkenler dahildir.

Peki, neden erişim belirleyicilere ihtiyaç duyarız?

Çünkü, uygulamamızda kullandığımız varlıkların bulundukları kod bloğunun dışından erişilip/erişilemeyeceğini belirlemek isteriz.

C# dilinde tanımlı erişim belirleyiciler (access modifiers);

public : public olarak tanımlanan öğe, kod bloğunun içinde ve dışında tamamen erişilebilirdir. Yani, hiçbir kısıtlama yoktur.

protected : protected olarak tanımlanan öğe, sadece tanımlandığı class’ın içinde ve o class’tan türetilmiş diğer class’ların içinde erişilebilirdir.

internal : internal olarak tanımlanan öğe, bulunduğu assembly’nin (Dll veya Exe dosyası) içinde erişilebilirdir. Dll veya Exe dosyasının içerisinde erişim için kısıtlama yoktur, ama dışarıdan erişilemez.

protected internal : protected internal erişim belirleyicisi, protected ve internal erişim belirleyicilerinin VEYA (OR) işlemiyle birleştirilmiş halidir. protected internal olarak tanımlanmış öğe, tanımlandığı class’ın içinde ve o class’tan türetilmiş diğer class’ların içinde erişilebilir. Ayrıca, aynı assembly içinde olmasalar dahi, tanımlandığı class’tan türetilmiş diğer class’ların içinde de erişilebilirdir.

private : private olarak tanımlanan öğe, sadece tanımlandığı class’ın içerisinde erişilebilirdir. En katı erişim belirleyicidir.

Aslında CLR içinde tanımlı bir erişim belirleyici daha vardır. FamilyAndAssembly olarak bilinir. C# kelimeleri ile benzetmeye çalışırsak, protected VE (AND) internal erişim belirleyicisidir. C# dili bu erişim belirleyicisini desteklemez, eğer kullanmanız gerekiyorsa, C++ ve direk IL yazmanız gerekmektedir.

class veya struct‘lar ya public, ya da internal olabilir, varsayılan olarak internal erişim belirleyicisine sahiptirler.

Varsayılan olarak class içerisinde tanımlı öğeler private erişim belirleyicisine sahiptirler.

struct içerisinde tanımlı öğeler public, internal veya private olabilirler. struct‘lar türetmeyi desteklemediği için protected ve protected internal erişim belirleyicisine zaten ihtiyaçları yoktur.