Struct | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar struct

LINQ ipucu – 1

15 September 2012 Yorum yapılmamış

Aldığı int parametre üzerinde çeşitli işlemler yapan ve elde ettiği sonucu geriye döndüren Hesapla() isminde bir method‘umuz var;

public int Hesapla(int Rakam)
{
	///parametre üzerinde gerçekleştirilen işlemler
	return Rakam;
}

Hesapla() method’unu çağıran aşağıdaki YapilacakIsler1() method‘u olsun;

public IEnumerable<int> YapilacakIsler1(IEnumerable<int> Rakamlar)
{
	var Sonuc = new List<int>();

	foreach (var r in Rakamlar)
	{
		Sonuc.Add(Hesapla(r));
	}

	return Sonuc;
}

YapilacakIsler1() method’unu, yield anahtar kelimesini kullanarak, IEnumerable<T> tipinde değişken oluşturmaya gerek kalmayacak şekilde değiştirebiliriz;

public IEnumerable<int> YapilacakIsler2(IEnumerable<int> Rakamlar)
{
	foreach (var r in Rakamlar)
	{
		yield return Hesapla(r);
	}
}

Hatta, LINQ Expression yazarak IEnumerable<T> tipindeki listedenin tüm elemanlarını Hesapla() method’una parametre olarak gönderebiliriz;

public IEnumerable<int> YapilacakIsler3(IEnumerable<int> Rakamlar)
{
	return Rakamlar.Select(r => Hesapla(r));
}

Son olarak, LINQ Select method’una Lambda Expression yerine, Hesapla() method’unu parametre olarak verebiliriz;

public IEnumerable<int> YapilacakIsler4(IEnumerable<int> Rakamlar)
{
	return Rakamlar.Select(Hesapla);
}

Yukarıdaki sadeleştirme devrimsel bir yenilik olmasa da, kodun daha derli-toplu olmasını sağlayacaktır.

Bu kodda ne yanlış var? – 8

13 June 2011 11 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# Windows’un Boş Zamanını (Idle Time) Bulmak

22 March 2011 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();
	}
}

C# ile Windows Sistem Saatini Ayarlamak

25 September 2010 5 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);

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

06 March 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()
	{
	}
}