Ağustos ayı blog kayıtları
HTML Application - [HTA Applications] Ümit Öncel

Yazar : Ümit Öncel

 

HTML Application ya da kısaca HTA, ilk olarak 1997 yılında Microsoft tarafından piyasaya çıkartılmış olan alternatif bir Windows uygulaması geliştirme dili. En güzel yanı ise Windows uygulamaları geliştirmek için sadece HTML bilmenin yeterli olması. Basit HTML komutları ile bir uygulama geliştirebileceğiniz gibi, hazırlamakta olduğunuz HTA?yı etkileşimli hale getirmek için script dillerini de kullanabilirsiniz. CSS desteği de sunan HTA, aynı zamanda kendine özgü bazı ek özelliklere de sahip.

Tüm bunlar sayesinde .hta uzantılı bu dosyalar bir HTML sayfasının sahip olduğu tüm avantajlara sahip olabiliyorlar. Daha da iyisi Windows tarafından güvenilir uygulamalar (Trusted Application) olarak kabul edilen HTA?lar, Web sayfalarından farklı olarak güvenlik ile ilgili kısıtlamalar ile karşılaşmadan çalışabiliyor. Eğer internet üzerinden veya farklı bir dış kaynaktan kullanılıyorsa, aynı EXE dosyalarında olduğu gibi kullanıcıya bir kez uygulamayı çalıştırmak mı yoksa kaydetmek mi istediği soruluyor. HTA dosyasını kendi bilgisayarınıza aldıktan sonra ise dilediğinizde sorunsuz olarak kullanabiliyorsunuz.

Bunun için tek yapmanız gereken hazırladığınız HTML dokümanını .hta uzantısı ile kaydetmek. Bundan sonra HTA?larınız, .exe uzantılı bir dosya gibi çalışmaya başlayacaktır.

 

C# veya VB gibi daha sofistike yazılım geliştirmeleri varken, HTML tabanlı bir Windows uygulaması geliştirmek pek çok kişiye ilk bakışta gereksiz gibi gelebilir. Ama özellikle geliştirmek istediğiniz uygulamalar çok karmaşık değilse, HTML?in basitliği size daha hızlı ve pratik bir yoldan işinizi tamamlama imkanı sunacaktır. Yapmak istediğiniz basit işlemler için C# veya VB gibi diller abartılı kaçabilir. Oysa HTA sayesinde sadece Not Defteri?ni kullanarak dilediğiniz script?i yazabilir, HTML?in avantajlarından faydalanarak basit ve göze hoş gelen bir arabirim hazırlayabilirsiniz. Üstelik tüm bunlar birkaç dakika içerisinde tamamlanabilir.

Şu anda tüm bunları bir HTML dokümanı ile de yapabileceğinizi düşünüyor olabilirsiniz, fakat ne yazık ki bu mümkün olamayacaktır. Internet Explorer veya benzer bir tarayıcıda pek çok güvenlik önlemi yer almaktadır. Hiç birimiz bir internet üzerinden eriştiğimiz bir sayfanın client-side script?ler çalıştırarak sistemimizi baştan aşağıya kendi istediği gibi yapılandırmasını istemeyiz. Dolayısıyla bir tarayıcı içerisinde çalışacak HTML sayfalarında bu tip script?ler çalıştırmak mümkün olmayacaktır. En iyi ihtimalle sayfada bir ActiveX kontrolü çalıştırılacağına dair bir uyarı ile karşılaşırız ve biz onaylamadan bu tip bir işlem gerçekleşemez.

Fakat aslında kökenlerini bir HTML sayfasından alıyor olmasına rağmen HTA?lar, tarayıcıların bu kısıtlamaları ile karşılaşmazlar. Bunun nedeni ise HTA dokümanlarının Internet Explorer ile değil, Microsoft tarafından sadece HTA dokümanlarını çalıştırmak üzere geliştirilen Mshta.exe ile çalıştırılmasıdır. Bu sayede HTA?lar client-side script?leri rahatlıkla çalıştırabilirler ve hiçbir uyarı ile de karşılaşmazlar. HTA?ların aynı EXE?lerde olduğu gibi okuma ve yazma iznine sahip olduklarını da hesaba katınca HTML?e göre bazı artıları olduğu daha iyi görülebiliyor.

Bunlar tabi ki Windows?un temel güvenlik önlemlerinin ortadan kaldırabileceği anlamına gelmez. Örneğin HTA ile kullanıcının izni olmayan hiçbir işlem gerçekleştirmek mümkün olmayacaktır.

 

 

 

 

 

 

Daha önce de söylediğimiz gibi HTA?ları hazırlamak son derece kolay. Not Defteri?ni açıp aşağıdakileri yazdıktan sonra .hta uzantılı olarak kaydederek ilk HTA?nızı hazırlayabilirsiniz.

 

<HTML> 
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-9">
<TITLE>İlk HTA Dokümanı</TITLE>
</HEAD>
<BODY>
HTA ile programlamaya başladınız bile?
</BODY>
</HTML>

 

Görüntüsü şu şekilde karşınıza gelmiş olmalı:

 

 

 

Gördüğünüz gibi bir HTML dokümanından hiçbir farkı olmamasına rağmen, internet tarayıcısında içerisinde açılmak yerine, bir Windows uygulaması olarak çalıştı. Bunu sağlayan dosyanın Windows tarafından tanınan .hta uzantısına sahip olması. HTA?nın kendine özgü özellikleri kullanabilmek için ise tek yapmanız gereken kodun <HEAD></HEAD> bölümleri arasında <HTA:APPLICATION etiketini eklemeniz.

 

Şimdi de yazmış olduğumuz kodu şu şekilde geliştirelim:

 

<HTML> 
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-9">
<TITLE>İlk HTA Dokümanı</TITLE>
 
<HTA:APPLICATION ID="Kimlik" 
APPLICATIONNAME="IlkHTA"
border="thick"
caption="yes" 
maximizeButton ="yes" 
minimizeButton ="yes"
showInTaskBar ="no"
singleInstance ="yes"
sysMenu ="yes"
windowState ="maximize">

</HEAD>
<BODY>
HTA ile programlamaya başladınız bile?
</BODY>
</HTML>

 

 

Görünüşte pek bir fark yok değil mi? Aslında son eklediğimiz satırlar ile birkaç önemli farka kavuşmuş oldu. İlk olarak bu kez program tam ekran açıldı. Çalıştırdığınızda görev çubuğunda yer almıyordu. Ve son önemli değişiklik ise sağ tuş ile tıkladığınızda karşınıza bir menü gelmiyor olmasıydı. Tüm bunları (ve biraz daha fazlasını) bu birkaç satır ile sağladık.

 

Aslında bu ufak gibi görünen detaylar, geliştireceğiniz bir uygulama için çok faydalı olabilir. Şimdi bu özel HTA komutlarının en önemlilerinin neler olduklarına bir göz atalım:

 

APPLICATION ID

Windows`un Script yorumlayıcısının kontrol edeceği kimlik bilgisi. Scipt?ler Id.applicationName şeklinde diğer özelliklerin kullanılabilmesini sağlarlar.


applicationName

Programınızın adı. Eğer SingleInstance kullanmak istiyorsanız, programın başka bir instance?ın çalışıp çalışmadığını kontrol edebilmesi için bir isim verilmesi şarttır.

 

border

Program çerçevesinin kalınlık değerini ifade eder. Thick (kalın), thin (ince), dialog(dialog pencesi), none (yok), normal olarak değer alabilir. Border değerinin ?none? olması başlık çubuğunu ve çubuktaki tüm öğeleri, çerçeve ile birlikte ortadan kaldırır. Border ?thin? olduğu zaman pencerenin boyutunu kenarlarından fare yardımı ile değiştirmek mümkün olmaz.


borderStyle

Programın içeriğindeki çerçevelerin stilini ifade eder. sunken(gömülü), raised(çıkıntılı), complex(aynı anda hem gömülü, hem çıkıntılı), static(standart) veya normal şeklinde değer alabilir.

 

caption

Programın başlık çubuğunu görüntülenip görüntülenmeyeceğine dair bir Boolean değer alır.

 

commandLine

Varsayılan bir değer taşımayan bu özellik, script ile kullanıldığında, .hta dosyasının çağırıldığı yolu taşıyan bir string döndür. alert("commandLine    = " + Id.commandLine) şeklinde kullanılabilir.

 

contextMenu

Sağ tuş ile tıklandığında ortaya çıkan menünün gösterilip gösterilmeyeceğine dair Boolen bir değer atanabilir.

 

icon

Programınızın sol üst köşesinde görünecek olan 32x32 piksel büyüklüğünde .ico uzantılı simgeyi tanımlamak için string türünden bir yol bilgisi atanabilir.

 

maximizeButton

Başlık çubuğunda büyütme simgesinin görüntülenmemesi için ?no? demelisiniz.


minimizeButton

Başlık çubuğundan programın küçültme imkanı vermek istemiyorsanız ?no? değeri vermelisiniz.

 

navigatable

Çalıştırılan ilk HTA dosyasının içerisinden, farklı HTML dosyalara verilen bağlantıların aynı pencere içerisinde kullanılıp, kullanılmayacağına dair string bir değer atanır. Eğer değer ?no? ise, bağlatı yeni bir tarayıcı içerisinde açılır. ?yes? ise HTA penceresi içerisinde görüntülenir.

 

scroll

Kaydırma çubuklarının kullanılıp kullanılmayacağını ifade eder. ?yes?, ?no? veya ?auto? olarak değer alabilir.

 

scrollFlat

Kaydırma çubuğunun üç boyutlu mu yoksa düz bir görüntüye mi sahip olacağını ifade eder.

 

selection

Fare veya klavye yardımıyla içeriğin seçili hale getirilip getirilemeyeceğini ifade eder. Varsayılan değeri ?yes?, yani seçime izin verme yönündedir.

 

showInTaskBar

Programın görev çubuğunda görünmesini istemiyorsanız ?no? yazmalısınız. Fakat bu durumda yine de ALT + TAB ile uygulamaya ulaşılabilir.


singleInstance

Bir kez çalıştırıldıktan sonra, yeniden farklı bir pencerede bir kez daha açılmasını istemiyorsanız buna da ?no? demelisiniz.

 

sysMenu

Programın başlık çubuğundaki, küçültme, büyütme ve kapatma simgelerini ortadan kaldırmak istiyorsanız ?no? yazmalısınız.

 

version

Hazırladığınız programın versiyon bilgisini taşımak için string bir değer atanabilir.


windowState

Program çalıştırıldığında açılacak olan pencerenin boyutunu belirler. Tam ekran açılması için ?maximize?, görev çubuğunda simge olarak açılması için ?minimize?, Internet Explorer?ın varsayılan büyüklüğünde açılması için ise ?normal? değeri atanabilir.

 

 

Bu özellikler ağırlıklı olarak, HTA?nın çalıştığı Windows penceresini kullanımına yönelik. Diğer yandan HTML ile yapılabilecekleri zaten biliyoruz. HTA?nın, HTML?den en büyük farkının script?leri kullanmak olduğunu söylemiştik. Dolayısıyla bu aşamadan sonra sıra scriptlerinizi eklemeye geldi.

Aynı HTML?de olduğu gibi bu da oldukça basit bir işlem. Tek yapmanız gereken <script></script> etiketleri içine kodunuzu yazmak. İşte VBScipt ile hazırlanmış ufak bir örnek. Bu örnek yardımıyla bilgisayarınızda çalışan işletim sistemi sayfaya yazdıracağız.

 

Aşağıdaki kodu çalıştırdığınızda karşınıza gelen görüntü şu şekilde olacak:

 

 

 

<head>
<title>HTA ile İşletim Sistemi Bilgisi Almak</title>
<HTA:APPLICATION 
     APPLICATIONNAME="IsletimSistemBilgisi"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
</head>
 
<script language="VBScript">
    Sub IsletimSisteminiOgren
        strComputer = "."
        Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
 
        Set colOperatingSystems = objWMIService.ExecQuery _
            ("Select * from Win32_OperatingSystem")
 
        For Each objOperatingSystem in colOperatingSystems
            DataArea.InnerHTML = objOperatingSystem.Caption & " " & _
                objOperatingSystem.Version
        Next
 
    End Sub
</script>
 
<body>
<input type="button" value="İşletim Sistemi" name="run_button" onClick="IsletimSisteminiOgren">
<p>
<span id = "DataArea"></span>
</body>

 

Bu, HTA?yı kullanarak yapabileceklerinize dair basit bir örnek. İhtiyaçlarınız doğrultusunda bundan çok daha fazlasını yapmak mümkün. Fakat ne yazık ki HTA geliştirmek ile ilgili kaynak bulmak pek kolay değil. Eğer HTA?nızda script?leri nasıl kullanabileceğinize dair daha fazla yardıma ihtiyacınız varsa, oldukça faydalı örnek kodlar içeren HTA Helpomatic adlı aracı şu adresten temin edebilirsiniz:

http://www.microsoft.com/downloads/details.aspx?FamilyId=231D8143-F21B-4707-B583-AE7B9152E6D9&displaylang=en


IEnumerable ve IEnumerator Arayüzleri ve Kullanımı

          Bu makalemiz de IEnumerable ve IEnumerator Interfacelerinden bahsediyor olacağız. Makalemize şöyle bir soru ile başlayalım. Normal şartlar altında bir dizi ile veya bir ArrayList nesnesi ile  kullandığımız foreach döngüsünü kendi yazdığımız  sınıf için de kullanabilir miyiz ?

Cevap : Hayır J

 

int[] sayilar=new int[10];

ArrayList liste = new ArrayList();

 

Yukarıdaki nesnelerin hepsinde foreach döngüsü ile çalışabiliriz. Fakat sorumuz şu ki :

 

class Ogrenci

{

}

 

class Sinif

{

            Ogrenci[] ogrenciler = new Ogrenci[20];

}

 

Sinif liste = new Sinif();

foreach (Ogrenci ogr in liste)

{

            //Kodlarımız...

}

 

şeklinde kullanamayız. Bunun sebebi foreach döngüsü üzerinde gezineceği nesnenin IEnumerable ve IEnumerator dedigimiz interfaceler den implemente etmiş olmasını ister.

Foreach döngüsü koleksiyonlar ve diziler üzerinde ilerlemek üzere hazırlanmıştır. Peki ben kendi yazdığım sınıf ile foreach döngüsünü kullanmak istiyorsam ne olacak ?

 

            Makalenin bundan sonraki bölümüne örneğimiz üzerinden devam edelim. Örneğimizde Ogrenci adında  bir class ve bir de Sinif isminde bir class olacak.

 

Ogrenci.cs :

    public class Ogrenci

    {

        public string isim;

        public string soyisim;

 

        public Ogrenci(string Isim, string  SoyIsim)

        {

            this.isim = Isim;

            this.soyisim = SoyIsim;

        }

    }

 

Sinif.cs :

 

    public class Sinif:IEnumerator,IEnumerable

    {

        Ogrenci[] liste = new Ogrenci[0];

 

        public void OgrenciEkle(Ogrenci ogr)

        {

            Array.Resize(ref liste, liste.Length + 1);

            liste[liste.Length - 1] = ogr;

        }

 

        public Sinif()

        {

        }

 

        int ind = -1;

 

        #region IEnumerator Members

 

        public object Current

        {

            get { return liste[ind]; }

        }

 

        public bool MoveNext()

        {

            if (++ind < liste.Length)

                return true;

            else

                return false;

        }

 

        public void Reset()

        {

            ind = -1;

        }

 

        #endregion

 

        #region IEnumerable Members

 

        public IEnumerator GetEnumerator()

        {

            return (IEnumerator)this;

        }

 

        #endregion

    }

 

Hazırladığımız iki sınıfı açıklayalım. Birinci class yani Ogrenci ismindeki sınıf sadece öğrenci bilgilerini taşımakla görevli. Ikinci class yani Sinif ise Ogrenci türünden degerleri alıp bunları kendi içerisinde ki Ogrenci dizisinde saklamakla görevli. Fakat Sinif ismindeki sınıfımızı foreach içerisinde kullanmaya çalıştığımız da eğer IEnumerable ve IEnumerator interface lerinden implemente etmezsek derleme anında şöyle bir hata alacağız :

 

foreach statement cannot operate on variables of type 'IEnumeratorIEnumerable.Sinif' because 'IEnumeratorIEnumerable.Sinif' does not contain a public definition for 'GetEnumerator'

Bu hata da belirtilen Sinif class ımızın GetEnumerator isminde bir üyeye sahip olmadığıdır. Foreach döngüsü çalışabilmek için bu metotu istediginden dolayı sınıfımızı IEnumerable interface den implemente etmeliyiz. Bununda haricinde foreach döngüsü tarafından kullanılan özel bir interface daha vardır ve üzerinde döndüğü koleksiyonda IEnumerator interface inin üyelerini görmek ister bunlar ise örnekte açıkça belirtilen

 

·         Current

·         MoveNext

·         Reset

 

üye metotları ve property leridir. Bu üyeler sayesinde foreach, sınıfımızın üzerinde gezerken dizinin elemanlarına ulaşabiliyor olacaktır.

 

IEnumerator Interface i hakkında detaylı bilgi için bu makaleden yararlanabilirsiniz

 

Örneğin Current isminde ki property okunduğu zaman kendisine Ogrenci[] dizimiz içerisinden index olarak üzerinde durulan Ogrenci sınıfını vereceğiz.

 

        public object Current

        {

            get { return liste[ind]; }

        }

 

Bu property ile ind ismindeki degiskenin degeri örnegin 5 ise Ogrenci dizimizin 5 indexli gözündeki Ogrenci sınıfını kullanıcıya object türünden geri döndürüyoruz.

 

MoveNext metotu :

 

  public bool MoveNext()

        {

            if (++ind < liste.Length)

                return true;

            else

                return false;

        }

 

Foreach döngümüz sınıf içerisinde ileri yönlü hareket edebilmek için MoveNext ismindeki metotumuzu kullanacaktır. Boolean türden deger döndüren bu metot döngüye dizinin son elemanına gelinip gelinmediğini bildirir. Böylece döngü ilerleyebildim mi yoksa ilerleyemedim mi gibi bir soruyu rahatlıkla sorabilir.

 

Reset ismindeki metot ise foreach döngüsünü dizinin ilk gözüne konumlandıracak olan metottur.

 

Bu kuralları uyguladıktan sonra artık sınıfınızı aşağıdaki şekilde kullanabilirsiniz :

 

 

            Sinif liste = new Sinif();

            liste.OgrenciEkle(new Ogrenci("haydar", "bağrıyanık"));

            liste.OgrenciEkle(new Ogrenci("muhittin", "Windows"));

 

            foreach (Ogrenci ogr in liste)

            {

                MessageBox.Show("Adı : " + ogr.isim+"\nSoyadı : "+ogr.soyisim);

            }

Bir sonraki makalede görüşmek üzere hepinize iyi çalışmalar

 

Sorularınız için mail adresim :   

bora.burgucugil@bilgeadam.com

BilgeAdam BTA Beşiktaş

 

 


Web Services and CookieContainer in .NET Framework 3.5

.NET Framework 3.5 ile birlikte WebServis projelerinde yer alan ufak bir değişiklikten bahsetmek istiyorum.

.NET Framework 2.0 zamanında bir web servis projesinde Session kullanmak için metot üzerinde EnableSession attribute bildirimi yapardık. Client uygulamanın session&pos;ı kaybetmemesi içinde client uygulama içerisinde CookieContainer tanıtırdık. .NET Framework 3.5 ile birlikte bu uygulama biraz değişti, artık CookieContainer tanıtıp bunu web servis nesnenizin CookieContainer property'sine atamıyorsunuz.

Artık client uygulamanızda açılan app.Config dosyasına gidip sadece allowCookies bildirimini true olarak değiştiriyorsunuz. Böylece container tanıtma ve bağlama işlemlerini çözmüş oluyorsunuz

Ufak ama önemli bir ayrıntı :)


C# 3.0 Specification

C# 3.0 ile ilgili specification dökümanına buradan erişebilirsiniz.


Web sitenize icon ekleyin

Geliştirmiş olduğunuz web sitenize internet explorer üzerinde icon eklemek için yapmanız gereken tek şey

<link rel="SHORTCUT ICON" href="images/myIcon.ico"/>

bildirimini sayfanızın html kodları arasına yerleştirmek :)

Ayrıntılı bilgi için :

 http://msdn2.microsoft.com/en-us/library/ms537656.aspx


Visual Studio 2008 Beta 2 ve Ajax 1.0

Herkese merhaba,
Microsoft Visual Studio Beta 2 versiyonunu
http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx linkinden indirebilirsiniz,
fakat dikkat etmeniz gereken bir durum sözkonusu.

VS 2008 Beta 2 yi kurduktan sonra .Net Framework 3.5 kurulumundan dolayı Ajax 1.0 dll leriniz çalışmayabilir ve tanınmayabilirler.

(Benim başıma geldiği için buraya yazıyorum :))

Bu problemden kurtulmak için kurulum sonrasında verilen uyarıya dikkat etmek gerekiyor

Important Instructions for Installing Visual Studio 2008 Beta 2
After the Beta 2 installation has finished, you should run this script to ensure that the installation of .NET Framework 3.5 Beta 2 will not affect the development of ASP.NET AJAX 1.0 applications.

bu uyarıda bir exe aracılığı ile bir scriptin çalıştırılması gerektiği söyleniyor (ki doğru :) )

Exeyi bir kere çalıştırdıktan sonra policy ile ilgili bazı değişiklikler yapılıyor ve Ajax 1.0 ile çalışmaya devam edebiliyorsunuz.

Zip dosyasını buradaki linkten indirebilirsiniz

İyi çalışmalar


Ajax ScriptManager

İleride çıkacak olan versiyonlarda değiştirilir mi bilemem ama şu anki versiyonda  Script Manager ın çalışması için her zaman HTML kodlarının en üstünde yer alması gerekiyor. Yani form altındaki ilk element ScriptManager olmalı.

Aksi taktirde Ajax kontrollerinizin çalışmadığını düşüneceksiniz :)

aman dikkat !!!


Ajax Slide Show Extender problemi

Biraz önce ajax slide show extender ile ilgilenirken farkettiğim bir problemden bahsetmek istiyorum.

Slide Show Extender bildiginiz gibi resimleri slayt geçişi olarak göstermeye yarayan bir tool fakat bu tool çalışırken html kod sırası olarak Image kontrolünün altında olmazsa çalışmıyor aman dikkat :)

 


Sonsuz kategori mantığı

Gelen sorular üzerine sonsuz kategori mantığını buraya eklemeye karar verdim.

Bilgisayar

   Laptop

      ASUS            

      IBM

   Desktop

      HP

      TOSHIBA

...

gibi bir kategorizasyona ulaşmak için en kısa yöntemlerden biri

KategoriID      KategoriAdi      UstKategoriId

1                     Bilgisayar            0

2                     Laptop               1

3                     Desktop            1

4                     ASUS               2

5                     IBM                  2

6                     HP                    3

7                     TOSHIBA         3

 

şeklinde bir tablo kurmaktır. Bu mantık sayesinde tek tablo ile kategori adımlarınızı sınırsız şekilde tanımlayabilirsiniz...

İyi çalışmalar

   


Sql Server&nbps;da bir tablodan random kayıt çekme

Select Top 1 * From Tablo Order By newId()

şeklinde bir sorgu ile sql server da duran herhangi bir tablonun kayıtlarından rastgele birini seçebilirsiniz.


GAC  a dll eklerken yaşanan problemin çözümü için link
http://support.microsoft.com/kb/306149
Global Assembly Cache problemi

Global Assembly Cache içerisine yazmış olduğunuz dll i eklerken, dll i Global Assembly Cache e attıktan sonra yapmanız gereken en önemli ve son adım :

Regedit editörü içerisinden :

[HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders

altına bir adet yeni key olusturmak

ve içerisine bir key eklemek. Değer olarak ise dll dosyanızın bulunduğu lokasyonu veriyorsunuz

"C:\\MyDllFolder\\" gibi

Ve herhangi bir proje içerisinden Add Reference dediğinizde artık dll karşınızda :)

İyi çalışmalar


Property Accessor Modifiers

            Property, Object Oriented Programming içerisinde hepimizin sıklıkla kullandığı bir yapıdır. Amacı temelde, değişkenlerin tanımlandığı sınıf dışarısından kontrolsüz değişikliğe uğramasını engellemek veya değer okuma işlemi yapılacağı zaman araya girip ister kontrol, ister değişik formatlarda değeri sunmaktır. Örneğin değişkenin alabileceği sınırlandırmak isterseniz bunu property aracılığı ile rahatça gerçekleştirebilirsiniz. Property kavramını hatırlayalım :

                       

    class Ogrenci

    {

        int _yazilim;

        int _sistem;

 

        public int Yazilim

        {

            get { return _yazilim; }

            set { _yazilim = value; }

        }

        public int Sistem

        {

            get { return _sistem; }

            set { _sistem = value; }

        }

    }

 

Yukarıdaki gibi bir sınıfımız olduğunu düşünürsek sınıf dışından sadece property ler erişilebilecektir. Bu sınıfın taşıyabileceği değerleri sınırlandırmak istersek :

 

using System;

using System.Collections.Generic;

using System.Text;

 

namespace PropertyAccessors

{

    class Program

    {

        static void Main(string[] args)

        {

            Ogrenci ogr = new Ogrenci();

            ogr.Yazilim = 150;

 

            Console.WriteLine("Not : " + ogr.Yazilim);

        }

    }

 

    public class Ogrenci

    {

        int _yazilim;

        int _sistem;

 

        public int Yazilim

        {

            get { return _yazilim; }

            set

            {

                if (value <= 100)

                    _yazilim = value;

            }

        }

        public int Sistem

        {

            get { return _sistem; }

            set

            {

                if (value <= 100)

                    _sistem = value;

            }

        }

    }

}

 

Çıktı :

 

 

Görüldüğü gibi kullanıcıyı rahatlıkla sınırlandırabiliyoruz. C# 2.0 ile birlikte gelen yeni bir yapı ise Property Accessor Accessibility kavramıdır. Bu yapı sayesinde artık bizim property accessor olarak nitelendirdiğimiz get ve set metotlarımızı da erişim belirteçleri ile sınırlandırabiliyoruz.

 

            Buraya kadar her şey güzel hiçbir sorun yok. Fakat bu property lere olan erişim tanımlandığı namespace haricinde başka bir namespace içerisinden mümkündür. Sebebi ise public olmalarıdır. Peki ya bizim senaryomuz şöyle oluşuyor olsaydı bu değişkenlerin değeri sadece aynı namespace dahilinde olan bir class tarafından değiştirilebilir. Yani PropertyAccessors isimli namespace haricinde bir yerden sadece okuma işlemi yapılacak olsaydı o zaman herkesin aklına farklı çözümler gelecekti ve kesinlikle bunu farklı yollar ile yapabilecektik. Örnek :

 

§          Değişkeni internal yaparım.

§          Bir metot hazırlarım internal olur sadece değişken değerini değiştirir vb

 

Fakat şöyle bir problem var ki property hala dışarıdan erişilebiliyor.

 

Peki çözüm ?

 

Çözüm olarak C# 2.0 ile birlikte eklenmiş olan özellikten faydalanacağız yani Property Accessor Modifiers.

 

Örnek :

 

    public class Ogrenci

    {

        int _yazilim;

        int _sistem;

 

        public int Yazilim

        {

            get { return _yazilim; }

            private set

            {

                if (value <= 100)

                    _yazilim = value;

            }

        }

        public int Sistem

        {

            get { return _sistem; }

            set

            {

                if (value <= 100)

                    _sistem = value;

            }

        }

    }

 

Sınıfımızı yukarıdaki şekilde hazırlarsak o zaman kullanılan yerler de bazı hatalar oluşacaktır.

 

 

 

Görüldüğü gibi Yazilim property artık değer kabul etmiyor. Sadece tanımlandığı class içerisinden deger kabul edecektir. En çok kullanım şekli tabi ki Set metotunun internal tanımlanması, get metotunun ise public olmasıdır.

 

    public class Ogrenci

    {

        int _yazilim;

        int _sistem;

 

        public int Yazilim

        {

            get { return _yazilim; }

            internal set

            {

                if (value <= 100)

                    _yazilim = value;

            }

        }

        public int Sistem

        {

            get { return _sistem; }

            internal set

            {

                this.Yazilim = 10;

                if (value <= 100)

                    _sistem = value;

            }

        }

    }

 

 

Şimdi gelelim her güzel konuda olduğu gibi kısıtlamalara. J

 

  • Hem get metotuna hem de set metotuna property accessor tanımlayamazsınız.
  • get veya set metotlarına vereceğiniz access modifier property nin erişim seviyesini geçemez. Hatta property erişim belirtecinden daha kısıtlı olmasını bekler derleyici.
  • Property accessor kullanabilmeniz için property nin hem get hem de set metotu tanımlanmalıdır. Biri bile yoksa bu özellikten faydalanamazsınız.

 

 

Böylece bir makalemizin daha sonuna geldik. Hepinize bir sonraki makalede görüşmek üzere iyi çalışmalar.

 

Sorularınız için mail adresim aşağıdadır.

bora.burgucugil@bilgeadam.com

BilgeAdam BTA Beşiktaş


Partial Types

                Visual Studio 2005 ile birlikte aslında hepimizin hayatına girmiş olan, birçoğumuzun ise hala farkında olmadığı yeni bir yapıdır partial types. Partial types sınıflarımızı (class), arayüzlerimizi (Interface) ve yapılarımızı (struct) partial anahtar kelimesi ile ayrı fiziksel dosyalarda tanımlayabilmemizi sağlayan yapıdır. ?Bu yapının bize sağladığı fayda nedir?? ?Neden bir class tanımlamasını ayırayım ki ?? Bunların cevabını açıklamadan önce şunu belirteyim Visual Studio 2005 kullanırken zaten istemeden hepimiz partial classlarla çalışıyoruz. Visual Studio 2005 içerisinde bir Windows Application açtığınızda karşınıza gelen Form1.cs ye baktığınızda göreceksiniz ki artık

 

public partial class Form1 : Form

 

şeklinde bir tanımlama söz konusu. Gelelim sorularımızın cevaplarına. ?Neden bir class?ı ayrı iki fiziksel dosya ya ayırayim ki ??. Eskiden beri her programcının baş belasıdır. Uzun ve karışık kodlar. Bunları aşmak için bazı standartlar var, okunabilirliği arttırma yönünde. Ama hepimiz biliyoruz ki, bir kod dosyası içerisindeki satır sayısı fazlalaştıkça okunabilirlik azalmakta. İşte bu yüzden Microsoft?unda tercih ettiği bir yöntem olan metotlar ile özelliklerin ve formdaki kontrollerin tanımlama bloklarını ayrı fiziksel dosyalara yazacağız. Yani formunuza yerleştirdiğiniz Button, Textbox vs. kontrollerin tanımı eskiden Windows Form Designer generated code olarak tanımlanan bir region içerisinde dururdu fakat artık ayrı bir dosya da duruyor. O dosyanın ismi de

Form1.Designer.cs. Bu kadar anlatımdan sonra biraz kodları görelim.

 

Eskiden (Visual Studio 2003) aşağıdaki gibi duran kodlar :

 

 

Artık Visual Studio 2005 içerisinde :

 

 

Şeklinde duruyor. Birde VS 2005 içerisinde ki solution explorer içerisine bakalım o zaman.

 

 

Resimde de gördüğümüz gibi VS 2005 içerisinde artık bizim Formlarımız artık en az 2 fiziksel dosya olarak açılmakta. Birinde bizim yazdığımız kodlar bulunacak. Diğerinde ise Visual Studio 2005 in bizim için oluşturduğu kodlar bulunacak. Birde Designer.cs uzantılı fiziksel dosyanın kodlarına bakalım.

 

 

Designer.cs uzantılı dosyada tutulan kodlar ise yukarıda ki şekilde görüldüğü üzere VS2003 te gördüğümüz her form için standart oluşturulan kodlar. Bunları gördükten sonra insanın aklına hemen e iki dosya varsa bunlar nasıl beraber çalışıyor gibi bir soru geliyor. Partial olarak işaretlenmiş fiziksel dosyalar derleyici için tek bir dosyaymış gibi işlem görürler. Daha açık konuşmak gerekirse. Bir class tanımladınız. Classın değişkenleri ve özellikleri bir fiziksel dosyada, class a ait metotlar bir dosyada dursun.

 

 

Yukarıdaki gibi bir class tanıtıyorum. Açılan classın kodlarına bi göz atalım.

 

 

görüldüğü üzere kodlarda bir fark görünmüyor. Şimdi hemen bir sınıf daha ekliyoruz.

 

 

Ekledikten sonra bir kere derliyoruz ve hatamızı görüyoruz.

 

 

Bu hatadan da gördüğümüz üzere classlarımızı tanımlarken partial anahtar kelimesini kullanmadık. Eğer class tanımlamalarımızı aşağıdaki şekilde değiştirirsek derleyici hatası almayacağız.

 

partialSinifim.Degislenler.cs

 

partialSinifim.Metotlar.cs :

 

 

O zaman anlıyoruz ki, bir sınıfı partial olarak işaretlemek istiyorsak tüm fiziksel dosyalarında class tanımlama satırına partial anahtar kelimesini yazıyoruz. Şimdi gelelim partial sınıfların bazı özelliklerine.

 

  • Partial olarak işaretlenen sınıflardan herhangi birinde class tanımlama satırında sealed, abstract, static şeklinde bir tanımlama var ise bunu tüm dosyalarda yazmak zorunda değilsiniz. Classlardan bir tanesine sealed yazsak dahi o classtan türeme yapamayacağız.

 

partialSinifim.Degiskenler.cs

 

 

partialSinifim.Metotlar.cs

 

 

Class1.cs :

 

 

Resimden de göreceğimiz gibi partialSinifim fiziksel dosyalarından sadece birinde sealed yazmamıza rağmen bu tanım tüm sınıf için geçerli oldu ve bu sınıftan türetme yapamaz hale geldik.

 

  • Partial anahtar kelimesi arayüzler(Interface) ve yapılar(struct) içinde kullanılabilir.

 

Bir makalemizin daha sonuna geldik. Bir sonraki makalemizde görüşene kadar herkese iyi çalışmalar.

 

Bora BURGUCUGİL

bora.burgucugil@bilgeadam.com

Bilge Adam Bilgi Teknolojileri Akademisi

Bireysel Yazılım Geliştirme Eğitmeni - Beşiktaş


Nullable Value Types

            Bu makalemizde .Net Framework 2.0 öncesinde ki ve .Net Framework 2.0 daki değer tipli değişkenlerin çalışma mantığındaki bir farklılıktan bahsediyor, örneklerle bu konunun inceliklerine değiniyor olacağız.

Tüm programcıların bildiği gibi değer tipli veri türleri yani sınıflarımız, nesnelerimiz ve string karakter katarı dışındaki tüm veri türleri değer tipliydi ve bu tipteki değişkenler null bilgisini taşıyamıyordu. Hatırlayacak olursak null değer taşımanın anlamı hiçbir nesneye ait  referans bilgisi taşımamasıydı. Bu konuyu biraz daha teknik olarak yorumlayacak olursak, değer tipli veri türleri oluşturulduklarında kendilerine STACK dediğimiz bölgeden yer alırlar ve bilgilerini kendi üzerlerinde taşırlar. Fakat referans tipli değişkenler bu durumdan biraz daha farklı olarak kendilerine taşınacak bilginin yer seçimi için HEAP dediğimiz bölgeyi seçerlerdi. Yani referans tipli nesnelerimiz HEAP bölgesinden kendilerine yer alıp referans bilgisini STACK içerisinde alacakları bölgeye yazarlardı. Bu yüzden onlara referans tipli diyorduk. Bu durumda referans tipli değişkenlerin null değer taşıması da anlamlandırılmış oluyordu. HEAP içerisinde hiçbir bölgeyi referans göstermemesi durumuna null değer taşıması da diyebiliyorduk. Bu bilgiler ışığında değer tipli veri türlerinin null değer taşıma gibi bir imkanı kalmamış oluyordu. Zaten bilgiyi kendi üzerinde taşıyan bir bölge söz konusu dolayısıyla bir referans söz konusu değil.

 

 

Yukarıda ki şekilde gördüğümüz integer tipten sayi1 isimli değişkene null bilgisi atayamayız. Atama yaptığımız takdirde derleme zamanında hata alırız.

 

Alacağımız hata ?Cannot convert null to ?int? because it is a value type? hatasıdır. Bunun anlamı null bilgi integer veri tipine çevrilemiyor çünkü integer değer tiplidir. (Hatanın tam Türkçesinin bu olmadığını bende biliyorum J anlamamız gereken bu ) Bu kodlardan da gördüğümüz gibi normal şartlar altında değer tipli bir değişkene null bilgisi yazamıyoruz. Peki referans tipli bir değişkene nasıl null bilgisi atıyoruz.

 

Not : burada snf instance için new yazmazsak yine snf null değerini taşıyacaktı fakat o zaman onu kullanmaya kalktığımda derleyici hatası alacaktık en azından ufak bir sahtekarlık ile derleyiciyi atlattık. J

 

Bu örnekteki snf isimli sınıf örneğimiz makale konusu olan null bilgiyide taşıyabilirler çünkü heap ile stack arasında bir referans ilişkisi olacaktır.

 

Artık değer tiplilerin neden null bilgisi taşıyamadığını bildiğimize göre asıl konumuza dönebiliriz. C# 2.0 içerisinde artık değer tipli değişkenlerimize de null bilgisini atayabiliyoruz. Nasıl yaptığımıza değinecek olursak :

 

Şekilde görüldüğü gibi herhangi bir değer türlü değişkene null bilgisi atayabilmek için değişkenin veri türünü belirttikten sonra ? karakterini ekliyoruz. Yani :

 

            Veri_türü? Değişken_adı;

Şeklinde bir tanımlama yaptığımız takdirde değer tipli değişkenlere de null değer ataması yapabiliyoruz. Bu tip bir kullanım nerede işime yarayacak dersek,  SQL Server  içerisinde her bir sütunumuzun ALLOW NULL isimli özelliğini vardı ve veri tipi ne olursa olsun database içerisinde her alana null değer atayabiliyorduk. İşte bu durumda örnek olarak datareader ile okuduğumuz herhangi bir tablodan null bilgisi dönüyorsa ve biz bu bilgiyi değer tipli bir değişkene atıyorsak runtime hatası alacağımız kaçınılmaz olur. Dolayısıyla ilk etapta bu tip sorunlardan kolayca kurtuluruz. Ayrıca kontrol yapmak zorunda kalmayız kısacası.

            Bu noktada gözden kaçırmamamız gereken ve bilmemiz gereken bir nokta daha var.

Null değer taşıyabilen değer tipli değişkenlerden, null değer taşıyabilir olarak işaretlenmemiş olan değer tipli değişkenlere bilinçsiz değer aktarımı yapılamayacağıdır.Ne demek istediğimizi yine örnek bir kodla açıklayalım.

 

 

Yukarıdaki şekilde de gördüğümüz gibi sayi1 isimli değişkenimizi null değer taşıyabilir olarak tanıttık fakat sayi2 isimli değişkenimizi bu yönde işaretlemedik. Bu yüzden yukarıdaki gibi bir atama söz konusu olduğunda ?Cannot implicitly convert type ?int?? to ?int?. An explicit conversion exists (are you missing a cast?)? şeklinde bir derleme zamanı hatası alıyoruz. Dolayısıyla null değer taşıyabilir şekilde işaretlediğimiz bir değer tipli değişkeni null değer taşıyabilir olarak işaretlenmemiş başka bir değişkene atanamaz. Atanması için bir şartın sağlanmış olması gerekmektedir. O şart da tür dönüşümüdür.

 

Not : yukarıdaki örnekte sayi1 = null yazan satırı sayi1 = 15 gibi uygun hale getirsenizde derleyici hatası alacaksınız. Dolayısıyla mutlaka çevirim yapılması gerekmektedir.

 

 

 

 

Yukarıda ki şekilde görüldüğü gibi sayi2 isimli null değer taşıyamaz olarak işaretlenmiş değişkene type casting ile artık sayi1 in değerinin atamasını yapabiliyoruz. Bu örnekte sayi1 null değer taşıdığı için runtime hatası alacağız o hatada

 

?Nullable object must have a value.? olacaktır. Bu örnekleri uç noktaları belli etmek için hazırladığım için hepsini görmenizi istedim. Peki şimdi bu tip bir sorunla bilerek karşılaşmıyorsak yani database içerisinden null bilgi döndü ise ve biz bunu nullable olarak işaretlediğimiz bir değişkene atadıysak daha sonra onu başka bir değer tipli değişkene atarken runtime hatası alacağız bunu nasıl çözeceğiz. Nullable değişkenlerin HasValue isminde bir property si var ve bu property bize bool tipten bir değer döndürüyor. Dolayısıyla bu tip bir atama yapılacağı zaman bu property kullanılabilir ve ortaya çıkabilecek olan hatalar engellenebilinir.

 

Şimdi bahsedeceğimiz başka bir konu ise nullable veri tipli değişkenlerin belirteci olan ? işaretinden yola çıkılarak oluşturulmuş bir operatör.

           

?? operatörü bizim için nullable değişkenler kullandığımızda işimizi çok kolaylaştıracak özelliklerini sunmaya başlıyor. Nasıl kullanılır ilk önce bunu açıklayalım isterseniz.

 

 

 

 

 

 

Yukarıdaki şekilde gördüğümüz gibi nullable bir değişken olan sayi1 den, null değer taşıyamayan sayi2 isimli başka bir değişkene değer aktarılmak isteniyor. Ama bunu şimdi farklı bir şekilde hallediyoruz. Tür dönüşümü kullanmadan hemde. Yukarıdaki kodda yapılan işlemin açıklaması ?: operatörüne benzer şekilde, eğer sayi1 isimli değişkenin değeri null değil ise sayi1 değerini sayi2 değişkenine aktar, şayet null ise sayi2 isimli değişken içerisine 0 değerini aktar. ?? operatörü tam olarak bu anlama gelmektedir. Eğer ?? operatörünün solundaki null değer taşıyabilir olarak işaretlenmiş değişken null değeri içermiyorsa onun değerini eşitliğin solundaki değişkene aktar, eğer null değer içeriyorsa ?? operatörünün sağındaki değeri eşitliğin solundaki değişkene aktar.

 

Nullable değer tipli veri türleri C# 2.0 ile birlikte hayatımıza girmeye başladı bile. Bunun yanında yakında C#2.0 ile ilgili birçok makale daha yayınlayacağız.

 

Bir sonraki makalede görüşmek üzere herkese iyi çalışmalar.


Refactoring

 

                Refactoring, Visual Studio 2005 ile birlikte hayatımıza getirilen pratikliklerden (veya kolaylıklardan da diyebiliriz) birisidir. Çok büyük yardımı yok gibi görünse de, proje geliştirirken birçok yeri ilgilendiren bir değişiklik yapmamıza olanak sağlar. Mesela bir kod bloğunu her sefer yazmak yerine bir metot yapmayı tercih edeceğimiz zaman,  bu ve bunun gibi detaylı şekilde inceleyeceğimiz, çok zaman alacak işlemler için Refactoring bize bir merkezi kontrol sistemi sağlıyor diyebiliriz.

 

                Şimdi Refactoring'in elemanlarını tanımaya başlayalım.

 

 

Ø Rename

Ø       Extract Method

Ø       Encapsulate Field

Ø       Extract Interface

Ø       Remove Parameters

 

 

RENAME :

 

                Refactoring? in Rename isimli elemanını kullanarak değişkenlerin (variables), metotların(methods),

sınıfların(classes), isim uzaylarının (namespaces), özelliklerin(properties) isimlerini kolayca değiştirebiliyoruz.

 

Kodumuzun şu şekilde olduğunu varsayalım ;

 

using System;

using System.Collections.Generic;

using System.Text;

 

namespace Refactoring_1

{

    class hesaplar

    {

        static int hesapID;

        public string hesapAdi;

        private decimal bakiye;

       

        public hesaplar(string hesapAdi, decimal bakiye)

        {

            hesapID += 1;

            this.hesapAdi = "";

            this.bakiye = 0;

        }

    }

}

 

Rename elemanını kullanabilmek için değiştirmek istediğimiz ismin üzerinde sağ klik yapıyoruz ve REFACTOR içerisinden RENAME menü öğesini seçiyoruz ve karşımıza yeni ismi isteyen bir dialog penceresi çıkıyor burada yeni ismi yazdıktan sonra alt tarafta bulunan checkbox lara bir göz atıyoruz.

 

 

İlk seçenek yani ?Preview reference changes? bu seçenek değişiklik gerçekleşmeden önce bize ufak bir pencerede değiştireceği yerleri gösteriyor. Böylece yanlış bir yeri değiştirme ihtimalimizi ortadan kaldırmış oluyoruz. Bu seçeneği pasif hale getirirsek bize bir ön izleme yapılmadan, tüm bulunan değerler, tüm proje içerisinde değiştirilecektir.

İkinci seçeneğimiz ?Search in comments?. Bu seçenek ise değiştirmek istediğimiz ismi, Visual Studio? nun geçersiz olarak işaretlenmiş ya da açıklama satırı olarak işaretlediğimiz yerlerde de araması için kullanılıyor.

                Üçüncü ve son seçeneğimiz ?Search in strings?. Bu seçeneğimiz ise seçtiğimiz ismin, proje içerisinde kullandığımız string ifadeler içerisinde de aranacağını veya aranmayacağını belirtiyor.

 

 

 

EXTRACT METHOD :

                Bir proje geliştirirken her programcının başına bela olan sorunlardan biridir kod tekrarı. Aynı kodu tekrar tekrar projenin ayrı yerlerinde yazmamak için metotları kullanırız. Metotlar C# dili içerisinde bir grup kod bloğunu çalıştırıp bize değer döndüren veya hiçbir şey yani void döndüren program parçacıklarıdır. Visual Studio 2005 metot tanımlamaları için Refactoring ile geliştiriciye bazı kolaylıklar sunmuş. Bunlardan biride Extract Method .

                Extract Method seçeneği bloklayarak seçtiğimiz bir grup kodu belirteceğimiz isme ve imzaya sahip bir metot haline getirmeye yarıyor. Bu seçeneğin biraz detaylarına girecek olursak :

 

                Extract method seçeneğini kullanabilmek için ilk önce metot haline dönüştüreceğimiz kod bloğunu seçiyoruz. Daha sonra bu seçili kod üzerinde sağ klik yapıp Refactor seçeneğinin üyelerinden Extract Method üyesini seçiyoruz ve işte her şey karşımızda. Visual Studio 2005 seçtiğimiz blok içerisindeki tanımlanmamış değişkenleri parametre haline getirip bizden sadece metota bir isim vermemizi bekliyor. Örnek olarak :

 

Basit bir toplama programı yazdığımız düşünelim girilen iki sayıyı toplayıp sonucu ekrana mesaj olarak gönderiyor.

 

 

 

private void button1_Click(object sender, EventArgs e)

        {

            int sayi1 = 0;

            int sayi2 = 0;

 

            sayi1 = Convert.ToInt32(textBox1.Text);

            sayi2 = Convert.ToInt32(textBox2.Text);

 

            int sonuc = 0;

 

            sonuc = sayi1 + sayi2;

 

            MessageBox.Show("Girilen iki sayının toplamı : " + sonuc);

        }

 

Bu kodu method haline getirmek istediğimizde bu kod bloğunu seçiyoruz. Daha sonra Extract Method üyesini seçiyoruz ve karşımıza yeni method ismini bekleyen bir dialog penceresi çıkıyor. Buraya yeni ismi verdikten sonra OK?e bastığımız anda projemizde verdiğimiz isim ile yeni bir method oluşturulacaktır. Visual Studio 2005

 

               

private void NewMethod(ref int sayi1, ref int sayi2)

 

 

bu şekilde bir method yaratacağını söyleyecektir. Verdiğimiz ismin de toplama olacağını varsayalım. Method

 

 

private void toplama(ref int sayi1, ref int sayi2)

 

 

 

halini alacaktır. Görüldüğü gibi blokladığımız kod içerisindeki sayi1 ve sayi2 değişkenleri tanımlanmadığı sadece kullanıldığı için onları ref anahtar kelimeli parametreler haline getirdi.bundan sonra bize sadece OK? e tıklamak kalıyor. OK? e tıkladığımız anda programımız içerisinde

 

 

        private void toplama(ref int sayi1, ref int sayi2)

        {

            sayi1 = Convert.ToInt32(textBox1.Text);

            sayi2 = Convert.ToInt32(textBox2.Text);

 

            int sonuc = 0;

 

            sonuc = sayi1 + sayi2;

 

            MessageBox.Show("Girilen iki sayının toplamı : " + sonuc);

        }

 

 

Şeklinde bir method oluşuyor ve bu kodu ilk yazdığımız ve seçtiğimiz yerde ise (class içerisinde) :

 

 

toplama(ref sayi1, ref sayi2);

 

 

 

şeklinde bir method çağırım satırı oluşuyor. Böylece extract method ile hem gereksiz kod tekrarından kurtulmuş, hem de daha kısa ve kolay şekilde istediğimiz kod bloğunu method haline getirmiş oluyoruz.

 

 

 

ENCAPSULATE FIELD :

                Yazdığımız her programda veya her class içerisinde kullandığımız değişkenlerin bazen sadece bizim yazdığımız class tarafından kullanılmasını isteyebiliriz. Ya da daha önceden yazdığımız bir class? ın bazı public değişkenlerinin dışarıdan direk erişilemez olmasını, bazı kontroller dahilinde değiştirilebilmesini isteyebiliriz Bu güvenlik daha doğrusu programın kontrollü ilerlemesi için önemli bir noktadır. Programımızda public olarak işaretlenmiş değişkenlere property aracılığı ile istediğimiz kullanım şartlarını yükleyebiliriz. Yani public olarak işaretlediğimiz bir değişkeni property haline getirirsek değişken tüm değer aktarımını property üzerinden yapacağı için Encapsulation işlemini gerçekleştirmiş oluruz. İşte Refactoring? in üyelerinden biri olan ENCAPSULATE FİELD ? da tam olarak bu işi yapmaktadır. Bizim seçtiğimiz bir değişkeni property haline getirmektedir. Bu da program içerisinde bize birçok yerde kolaylık sağlayacaktır. Örnek olarak :

 

 

  class hesaplar

    {

        static int hesapID;

        public string hesapAdi;

        public decimal bakiye;

 

        public hesaplar()

        {

            hesapID += 1;

            this.hesapAdi = "";

            this.bakiye = 0;

        }

    }

 

Şeklinde bir sınıfımızın olduğunu varsayalım.Bu sınıfta iki tane dışarıdan erişilebilir, public olarak işaretlediğimiz değişken tanımlı. Bu değişkenlere kullanıcı istediğini atayarak istediğini yapabilir. Bu programımızın bir sonraki versiyonunda bakiye isimli alanın biraz daha önem kazanması gerektiğini düşünüp, bu alana daha kontrollü bilgi aktarılması gerektiğini sağlamaya çalışıyoruz. Bu değişkenin bir property aracılığı ile kontrol edilmesi gerektiğine karar veriyoruz.Bunu yapmak içinde Refactoring? den yararlanıyoruz.

 

 

Refactoring içerisinden Encapsulate Field seçeneğini seçiyoruz. Bizden yeni oluşturacağımız property için bir isim girmemiz isteniyor. Yeni bir isim verdikten veya OK? e tıkladıktan sonra karşımıza bir önizleme penceresi çıkıyor (seçime bağlı preview reference changes üyesini seçmezsek çıkmaz) ve APPLY dediğimiz takdirde projemizde aynı scope içerisine bir property tanımı yapılıyor. Bu işlemden sonra kodumuzu kontrol ettiğimizde Refactoring işlemi sonucu değişkenimiz otomatik olarak private yapılıyor ve altına property tanımı ekleniyor. Artık diğer class? lar bu değişkeni değil yeni oluşturduğumuz propery? i kullanacaklar. Kodun son hali ise :

 

 

    class hesaplar

    {

        static int hesapID;

        public string hesapAdi;

        private decimal bakiye;

 

        public decimal Bakiye

        {

            get { return bakiye; }

            set { bakiye = value; }

        }

 

        public hesaplar()

        {

            hesapID += 1;

            this.hesapAdi = "";

            this.bakiye = 0;

        }

    }

 

 

 

EXTRACT INTERFACE :

 

Hepimizin bildiği gibi Arayüzler(Interface) sadece tanım bilgilerini tutarlar ve genellikle kodlama, geliştirme yapılmadan önce oluşturulurlar. Oluşturduğumuz bir sınıfın Interface? ini hazırlamak istediğimizi varsayarsak, tüm sınıf kodlamasını baştan sona gözden geçirip ona göre bir Interface hazırlamamız gerekir. Fakat Refactoring bu anlamda da bize büyük bir kolaylık sağlıyor. Refactoring içerisindeki Extract Interface seçeneği bizim oluşturduğumuz veya daha önceden oluşturulmuş bir class için Interface oluşturmamızı sağlıyor. Bu noktada dikkat etmemiz gereken bir nokta var o da oluşturacağımız Interface Class? ta public metotların bulunması gereğidir. Örnek olarak bir önceki kodumuzdan gidecek olursak :

 

 

    class hesaplar

    {

        static int hesapID;

        public string hesapAdi;

        private decimal bakiye;

       

        public decimal Bakiye

        {

            get { return bakiye; }

            set { bakiye = value; }

        }

 

        public hesaplar()

        {

            hesapID += 1;

            this.hesapAdi = "";

            this.bakiye = 0;

        }

     }

 

 

Şeklindeki sınıfımızdan bir Interface oluşturmak istediğimizi varsayalım. Class üzerinde Refactor elemanlarından Extract Interface seçeneğini seçtiğimizde karşımıza ufak bir dialog penceresi çıkacaktır.

 

 

Bu pencerede Interface için isim, Interface dosya ismi (*.cs)  ve son olarak da bu interface? e ekleyeceğimiz public method veya propertylerin seçilmesi gerekiyor. Bunların hepsini tamamladıktan sonra OK diyoruz ve karşımıza :

 

 

using System;

namespace Refactoring_1

{

    interface Ihesaplar

    {

        decimal Bakiye { get; set; }

    }

}

 

 

Şeklinde Ihesaplar.cs isminde bir interface oluşturulup getiriliyor.Bu işlem sonucunda sınıfımızda bu interface? den türer hale getirilir, yani :

 

 

class hesaplar : Refactoring_1.Ihesaplar

 

 

halini alır.

 

 

 

REMOVE PARAMETERS :

                Belirttiğimiz metot veya yapılandırıcının parametrelerini silmemize yarar. Minimum 1 parametreli metot veya yapılandırıcılar üzerine uygulanabilir.

 

        public hesaplar(string hesapAdi, decimal bakiye)

        {

            hesapID += 1;

            this.hesapAdi = "";

            this.bakiye = 0;

        }

 

Şeklindeki kodumuza uygulamak istersek eğer çıkacak olan dialog penceresi aşağıdaki gibidir.

 

 

REORDER PARAMETERS :

                Belirtilen metot veya yapılandırıcının parametrelerinin sırasını değiştirmeye yarar. Minimum 2 parametreli metot veya yapılandırıcılar üzerine uygulanabilir.

 

bora.burgucugil@bilgeadam.com