• Anasayfa
  • Hakkımızda
  • Etkinlikler
  • Destek Verin
  • Site Haritası
  • Giriş Yap
  • Üye Ol
  • Facebook
  • Twitter
  • RSS
Yazılım Dilleri
  • Soru - Cevap
  • EĞİTİM SETİ
  • KATEGORİ
  • DUYURU
  • TEKNOLOJİ HABERLERİ

Son Sorular

  • 23.04.2016 00:55:33C programlama 2 oyun
  • 20.04.2016 16:34:41Local Database
  • 15.04.2016 14:26:15Fatura kayıt işlemi
  • 21.03.2016 01:55:30C# problem

Popüler Sorular

  • 27.05.2012 05:49:50Asp.Net ile Date time alana veri ekleyemiiyorum ?
  • 2.04.2012 00:45:18.exe uzantılı dosya için dijital imza nerde nasıl alınır.
  • 12.05.2012 08:44:49Acil Yardım
  • 27.05.2012 13:46:51veri tabanı bağlantısı
  • .Net Framework
  • 8085 Assembly
  • Active Directory
  • ADO.NET
  • Android
  • Apple IOS
  • Arduino
  • ASP.NET
  • ASP.NET MVC
  • Blackberry
  • C#.Net
  • C++
  • CCG Framework
  • CISCO
  • CSS
  • Diğer
  • Dreamweaver
  • Entity Framework
  • Exchange Server
  • Gömülü Sistemler
  • GSM Programlama
  • Güncel
  • Güvenlik
  • HTML5
  • Java
  • Javascript / JQuery
  • Jira
  • Kariyer ve İş Yaşamı
  • LINQ
  • LibreOffice
  • Linux
  • Matlab
  • Microsoft Dynamics CRM
  • Mobil Uygulama Geliştirme
  • MySQL
  • NoSQL
  • Oracle
  • OWIN
  • PFSense
  • PHP
  • Powershell
  • Python
  • Sanallastirma
  • SAP-ABAP
  • SCOM 2012
  • SEO
  • Sharepoint 2010
  • Sharepoint 2013
  • Silverlight
  • Sistem Analiz ve Tasarımı
  • SQL Server
  • Symantec
  • TFS
  • T-SQL
  • Ubuntu
  • VB.NET
  • Veritabanı Yönetim Sistemleri
  • Visual Studio
  • VMware
  • WCF
  • Web Hosting
  • Windows 8
  • Windows Azure
  • Windows Phone 7.1
  • Windows Phone 8
  • Windows Server
  • Wordpress
  • WPF
  • Xamarin
  • XNA
  • Yazılım Mühendisliği
  • Yöneylem Araştırması
  • ASP.NET MVC
  • Entity Framework
  • Javascript / JQuery
  • LINQ
  • PHP

Son Duyurular

IPhone 6 ve IPhone 6 Plus Teknik Özellikleri ve Fiyatı

IPhone 6 ve IPhone 6 Plus Teknik Özellikleri ve Fiyatı

DELL'in Yeni Projesi: USB Bilgisayar (Project Ophelia)

DELL'in Yeni Projesi: USB Bilgisayar (Project Ophelia)

Windows Phone Youtube Uygulaması Google ve Microsoft ile Yeniden Yapılıyor

Windows Phone Youtube Uygulaması Google ve Microsoft ile Yeniden Yapılıyor

Android ve Apple IOS Telefonlar için Blackberry Messenger (BBM)

Android ve Apple IOS Telefonlar için Blackberry Messenger (BBM)

Nokia Lumia 925 Teknik Özellikleri, Lumia 928 ve 920 ile Karşılaştırması

Nokia Lumia 925 Teknik Özellikleri, Lumia 928 ve 920 ile Karşılaştırması

LG Optimus G Pro Özellikleri ve Gözle Video Oynatma Teknolojisi

LG Optimus G Pro Özellikleri ve Gözle Video Oynatma Teknolojisi

C# 6.0 Yenilikleri ve Örnek Kodlar

Build konferansının ardından gözümüze çarpan C# 6.0 dil yeniliklerini, Roslyn End User Preview üzerinden incelemeye çalışıyoruz.

09.04.2014

Yazar: Burak Selim Şenyurt (Google+)

Kategori: C#.Net

9139

Çok şanslı bir çocukluk geçirdim. 80li yıllarda daha minik bir çocukken Lego’ lar oyuncak dolabımdan eksik olmazdı. O zamanlar benim için çok kıymetliydiler. Tabi büyüdükçe başka başka şeyler önem kazanmaya başladı.Lego’ nun pabucu belki de dama atıldı. Ta ki bir oğlum olana kadar.

Şimdiler de 4lü yaşlarını yaşayan S(h)arp Efe’ nin en sevdiği oyuncakların başında geliyor Lego. Ülkemizdeki fiyatları her ne hikmetse yüksek olan Lego’ lardan çok fazla alamıyoruz belki ama işin güzel bir tarafı var. 80li yıllarda oynadığım ve Annem tarafından saklanan Legoparçaları günümüzdekiler ile de uyumlu. Yani var olanları yeniler ile bir arada kullanıp hayal gücümüze göre farklı farklı yapılar inşa edebiliyoruz.

İngilizce kelime anlamı Build olan inşa etmek(yapmak, kurmak) üzerine bu aralar uzak uzak diyarlarda da yapılmakta olan konuşmalar da var. Evet tahmin ettiğiniz gibi Microsoft’ un Buildetkinlikleri dolayısıyla yazılım dünyasında hareketli günler yaşanmakta. Yeni ürünler, var olan ürünlere eklenen yeni özellikler, gelecek ile ilişkili planlamalar ve diğerleri. Konuşulabilecek ve üzerinde durulabilecek pek çok konu var. Benim dikkatimi çeken nokta ise bir süredir varlığından haberdar olduğumuz ve şu anda Roslyn’ in End User Preview sürümü ile Visual Studio 2013üzerinden anında inceleyebileceğimiz C# 6.0 dili ile ilişkili yeni kabiliyetler. Bu yazımızda söz konusu yeteneklerden bir kaçına kısaca değinmeye çalışacağım. Amacımız öncelikli olarak söz konusu bu yeteneklerin ne olduklarını kavrayabilmek.

Dilin şu anki Preview sürümüne eklenen özellikleri zaman içerisinde değişime uğrayabilir. Ayrıca son sürüme geldikten sonra bu kabiliyetlerin bana kalırsa kendisini endüstüriyel anlamda ispat etmesi de önemlidir.

Ön Hazırlıklar

C# veya VB dillerinin gelecek nesil versiyonunda planlanan yenilikleri şimdiden test etmek içinRoslyn End User Preview kullanılabilir. İlgili sürümü Bu adreste indirilebilir ve kendimizi esintilerin akışına bırakabiliriz. Ayrıca güncel C# ve VB dil gelişimlerini, özellik bazında şu adrestentakip edebiliriz. Bu adresteki tabloda halen planlanan, tamamlanmış olan, uzun süredir var olan veya dilin bu versiyonunda düşünülmeyen kabiliyetler tablo halinde bilgimize sunulmaktadır. (Sık sık uğrayıp güncellemeleri takip etmekte yarar olduğu kanısındayım)

End User Preview’ u içeriğini indirip gelen vsix dosyasını yükledikten sonra yeni özellikleri hemen denemeye başlayabiliriz. Ayrı bir proje şablonu oluşturmamıza gerek yoktur. Ben yeni özelliklerden gözüme kestirdiklerimin bir kaçını incelemek üzere, basit bir Console uygulaması üzerinden ilerlemeye çalışacağım.

Auto Property Initializers

Auto Property uzun süredir kullanmakta olduğumuz bir dil kabiliyeti. Özellikle Entity Frameworktarafında POCO(Plain Old CLR Object) tiplerin tanımlanmasında yaygın bir şekilde ele alınmakta. Ben de açıkçası çok uzun zamandır property tanımlamalarında get ve set bloklarını kullanmıyor, sınıf içi alanlar açıkça değer atama veya onlardan veri okuma işlemlerini yazmıyorum. C# 6.0sürümünde planlanan ve şu anda Roslyn End User Preview' da test edebildiğimiz yeni yetenek ise söz konusu Auto Property' lerin ilk değerlerinin verilmesi ile alakalı. Bu anlamda aşağıdaki kod parçasını göz önüne alabiliriz.

using System;

namespace NewFeatures 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            ConnectionManager manager = new ConnectionManager(); 
            Console.WriteLine("Client ID:{0}\nConnection String:{1}",manager.ClientID,manager.ConnectionString); 
            manager.ClientID = -1; 
            Console.WriteLine("New Client ID:{0}",manager.ClientID); 
        } 
    }

    #region Auto Property Initializers 
    class ConnectionManager 
    { 
        public string ConnectionString { get; } = "data source=.;database=Core;integrated security=sspi"; 
        public int ClientID { get; set; }= 99; 
    } 
    #endregion 
}

Bu kod parçasında görüldüğü üzere ConnectionString ve ClientID isimli özellikler tanımlandıkları satırda ilk değerlerine sahip olmaktalar. İfade noktalı virgül ile tamamlandığında hem özellik tanımını hem de bu özelliklere ait arka plan alanları(Backing Field) için ilk değerleri vermiş oluyoruz. Bu arada ConnectionString' in sadece okunabilir(Readonly) bir özellik olarak tanımlandığına dikkat edelim. Çalışma zamanı sonuçlar aşağıdaki gibidir.

Tabi arka planda yer alan IL(Intermediate Language) görüntüsüne bakmakta da yarar var ki o da şu şekildedir.

Dikkat edilmesi gereken nokta özellik değerlerinin ConnectionManager sınıfının yapıcı metodu(Constructor) içerisinde atanmış olmasıdır.

Primary Constructors

Bildiğiniz üzere yapıcı metodların pek çok farklı versiyonu bulunmakta. Static Constructor, Copy Constructor, Default Constructor ve tabi Overload edilmiş versiyonları. Hatta yapıcı metodlarınbase ve this anahtar kelimelerinin de işin içerisine katılmasıyla üst sınıf veya aynı sınıftaki öncelikli yapıcı metoda parametre taşıyan versiyonları da mevcut. C# 6.0’ ın planlanmış yeni kabiliyetlerinden birisi de Primary Constructor olarak karşımıza çıkmakta. Buna göre aşağıdaki gibi bir sınıf inşası mümkün.

using System;

namespace NewFeatures 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            Segment rZone = new Segment("RED", 1900); 
            Console.WriteLine("{0} {1}",rZone.Code,rZone.Length); 
        } 
    }

    #region Primary Constructors

    class Segment(string code,int length) 
    { 
        public string Code { get; }=code; 
        public int Length { get; }=length; 
    } 
    #endregion 
}

Segment isimli sınıf inşa edilirken parantezler içerisinde iki değişken tanımlaması yapıldığı görülmektedir. Bu, aslında code ve length isimli parametreleri kullanan bir yapıcı metod(Constructor) tanımlamasıdır. Örnekte yapıcı metodun daha anlamlı hale gelmesi adına, ilgili metod parametrelerinin Read Only olarak ifade edilmiş Auto Property' ler de ilk değerler olarak kullanılması sağlanmıştır. Dolayısıyla Segment tipinden bir nesne örneği oluşturulurken, yapıcı metod içerisinde verilen değerler aynı zaman da Code ve Length özelliklerinin set edilmesinde kullanılmaktadır. Çalışma zamanı görüntüsü aşağıdaki gibidir.

Ama bizi asıl ilgilendiren kodun IL tarafına nasıl yansıdığıdır. İşte o görüntüler.

Dikkat edileceği üzere yapıcı metod için code ve length isimli argumanlar tanımlanmış ve bu argumanlara ait değerler Segment ve Code özelliklerine ait alanlara ldarg.1 ve ldarg.2 üzerinden atanmıştır.

Şu da bir gerçek ki normal şartlarda bu tip bir sınıfı aşağıdaki gibi yazardık.

class SegmentV2 
{ 
    private string _code; 
    private int _length; 
    public int Length { get { return _length; } } 
    public string Code { get { return _code; } }

    public SegmentV2(string code,int length) 
    { 
        _code = code; 
        _length = length; 
    } 
}

Ama bu, Primary Constructor özelliğinin "kodu kısaltarak daha kolay ve kullanışlı hale getirmiştir"şeklinde yorumlanmasını gerektirmez.

Primary Constructor kullanıldığında dikkat edilmesi gereken bir durumda diğer yapıcıların nasıl yazılabileceğidir. Örneğin aşağıdaki gibi bir varsayılan yapıcı metod(Default Constructor)tanımı derleme zamanı hatasına neden olacaktır.

class Segment(string code,int length) 
{ 
    public string Code { get; }=code; 
    public int Length { get; }=length;

    public Segment() 
    { 
    } 
}

Bu son derece doğaldır nitekim Primary Constructor sınıfı başlatmak için gerekli olan minimum argüman desenine sahip yapıcıyı tanımlamaktadır. Dolayısıyla aşağıdaki gibi bir kullanıma gidilmesi gerekecektir.

using System;

namespace NewFeatures 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            Segment gZone = new Segment(); 
            Console.WriteLine("{0} {1}", gZone.Code, gZone.Length); 
        } 
    }

    #region Primary Constructors

   class Segment(string code,int length) 
    { 
        public string Code { get; }=code; 
        public int Length { get; }=length;

        public Segment() 
            :this("GZONE",980) 
        { 
        } 
    }

    #endregion 
}

IL koduna baktığımızda varsayılan yapıcı metodun beklendiği gibi Primary Constructor' un işaret ettiği fonksiyonu çağırdığı görülmektedir.

Static Metodlar için using Bildirimi

Enteresan ve aslında hoşuma giden özelliklerden birisi de, static metodların tanımlandıkları tip adına ihtiyaç duymadan çağırılabilmeleri. Aynen aşağıda kod parçasında görüldüğü gibi.

using System; 
using System.IO.Path;

namespace NewFeatures 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            #region Static Metodların Kullanım

            var logFile=Combine(Environment.CurrentDirectory, "Logs.txt"); 
            Console.WriteLine(logFile);

            #endregion 
        } 
    } 
}

Dikkat edileceği üzere using System.IO.Path şeklinde bir bildirim yapılmıştır. Bu bildirim nedeniylePath sınıfının static metodlarından Combine, tanımlandığı sınıf adı belirtilmeksizin kullanılabilmiştir. (Normal şartlarda Path.Combine şeklinde bir kullanım olduğunu hatırlayalım)

Bu kullanım şekli genişletme metodları(Extension Method) için de geçerlidir. Aşağıdaki kod parçasında olduğu gibi.

using System; 
using System.Data; 
using NewFeatures.DataExtensions;

namespace NewFeatures 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            #region Static Metodların Kullanım

            LoadFromExcel(new DataTable(), "");

            #endregion 
        } 
    }

    static class DataExtensions 
    { 
        public static DataTable LoadFromExcel(this DataTable Table,string Source) 
        { 
            throw new NotImplementedException(); 
        } 
    } 
}

DataExtensions sınıfı içerisinde yer alan LoadFromExcel genişletme metodunu, tip adı olmadan kullanabilmek için

using NewFeatures.DataExtensions;

şeklinde ki tanımlama yeterli olmuştur.

Decleration Expressions

Bu kabiliyeti anlamak için aşağıdaki kod parçasını göz önüne alarak işe başlamamız gerekiyor.

using System;

namespace NewFeatures 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            #region Decleration Expressions

            string cDate = "2014-04-04 10:30:00"; 
            DateTime result; 
            if(DateTime.TryParse(cDate, out result)) 
            { 
                // do something 
                Console.WriteLine(result.ToString()); 
            } 
            
            #endregion 
        } 
    } 
}

Tipik olarak string bir içeriğin DateTime tipine dönüşümünün TryParse metodu ile kontrollü hale getirildiği bir senaryo söz konusudur. Decleration Expressions sayesinde aynı kod parçası aşağıdaki gibi yazılabilir.

using System;

namespace NewFeatures 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            #region Decleration Expressions

            string cDate = "2014-04-04 10:30:00"; 
            if(DateTime.TryParse(cDate,out DateTime result2)) 
            { 
                Console.WriteLine(result2.ToString()); 
            } 
            
            #endregion 
        } 
    } 
}

Dikkat edilmesi gereken nokta tahmin edileceği üzere TryParse metodunun ikinci parametresinde bir değişken tanımının yapılmasıdır. result2 parametre olarak kullanılacağı yerde aynı zamanda değişken olarak tanımlanmıştır. IL içeriğine baktığımızda beklediğimiz gibi result2’ nin dışarıda birlocal değişken olarak yerleştirildiği gözlemlenecektir.

Bu yetenek özellikle out gibi parametrelerin kullanıldığı yerde ön plana çıkmaktadır.

Dictionary Initializers

Dictionary tipinden bir koleksiyonu nasıl oluşturursunuz? Kuvvetle muhtemel aşağıdaki kod parçasında görüldüğü gibi.

Dictionary<int, string> values = new Dictionary<int, string>   
{ 
    { 1,"Red" }, 
    {9,"Green" }, 
    {4,"Blue" } 
};

Aynı koleksiyonu yeni gelen Initilaization yapısı ile aşağıdaki şekilde de oluşturabilmekteyiz.

Dictionary<int, string> valuesV2 = new Dictionary<int, string> 
{ 
    [1]="Red", 
    [9]="Green", 
    [4]="Blue" 
};

Doğrudan index bilgisini kullanarak Microsoft’ un kaynaklarına göre daha şık bir atama söz konusu . Ancak işin asıl dikkat çekici tarafı aşağıdaki gibi yapılabilen koleksiyon tanımı.

using System; 
using System.Collections.Generic;

namespace NewFeatures 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            #region Dictionary Initilaziers

            var values = new Dictionary<string, string> 
            { 
                $code="G-ZONE", 
                $length="1900", 
                $creationTime=DateTime.Now.ToLongTimeString(), 
                $identity=Guid.NewGuid().ToString(), 
                $color="Green" 
            };

            Console.WriteLine( 
                "{0}\n{1}\n{2}\n{3}" 
                , values.$code 
                , values.$creationTime 
                , values.$identity 
                , values.$color 
                );           

            #endregion 
        } 
    } 
}

Sanırım bu yazım şekli biraz daha dikkatinizi çekmiştir. values isimli generic Dictionarykoleksiyonunun içeriği belirlenirken $keyName şeklinde bir kullanım söz konusudur. Bu kullanımın faydası, values değişkeninin key değerlerine erişirken kendisini göstermektedir. Her ne kadar şu anda intellisense bir yardımda bulunmasa da JSON vari bu yazım şekli oldukça kullanışlıdır. İşte çalışma zamanı sonuçları.

Başka Neler Var?

Henüz inceleme fırsatı bulamadığım Exception Filters ve try…catch…finally bloklarında awaitkullanımı dışında plan dahilinde olan pek çok yeni kabiliyet gelecek dönemlerde bizleri beklemekte. Örneğin IEnumerable<T> tipinin params ile metodlarda kullanılabilmesi, yapıcı metod seviyesinde tahmin edilebilirlik(Constructore Inference), Event Initializers, private protected ve diğerleri. Plan dahilinde olan yetenekleri şu anki Preview sürümünde kullanamadım. Anlayacağınız takipte olacağız!

Sonuç

Doğruyu söylemek gerekirse yeni gelen dil özelliklerinin daha yalın ve sade kod üretimi noktasında katkılar sağladığı ilk göze çarpan noktalar arasında. Bu, Clean Code olarak nitelendirdiğimiz okunabilir, yönetilebilir, bakımı daha kolay yapılabilir, hata yapma olasılığını azaltan kod parçalarının oluşmasında önemli bir dayanak noktası. Ancak söz konusu özelliklerin gerçekten hayat kurtardığı veya “farklı olarak şu işe” yaradığını söylemek için sanırım biraz erken. Ben de halen çoğunu özümsemeye ve farklı faydalarının neler olabileceğini kavramaya çalışmaktayım.

Önemli olan noktalardan bir diğeri aslında CLR’ ın ve IL tarafının oldukça iyi tasarlanmış olduğu gerçeği. (Sanki 80li yıllardaki Lego parçalarının üstüne günümüz modellerini sorunsuz ve kolayca entegre edebilmek gibi) Dikkat edileceği üzere incelediğimiz yeni yeteneklerin çoğu syntax açısından kolaylıklar gösterse de IL tarafında beklediğimiz şekillere dönüşmekte. Dolayısıyla syntax tarafında planlanan bir kabiliyetin aslında IL tarafında karşılığı olmasının, bu yeni yeteneğin ortaya konulmasının sırrı olduğunu ifade edebiliriz.

İlerleyen dönemlerde söz konusu özelliklerin endüstüriyel anlamda faydalarını göreceğimizi umuyorum. Böylece geldik bir yazımızın daha sonuna. Tekrardan görüşünceye dek hepinize mutlu günler dilerim.

Yazar Hakkında

Burak Selim Şenyurt

Burak Selim Şenyurt

buraksenyurt.com

Yıldız Teknik Üniversitesi Matematik Mühendisliği mezunu olan Şenyurt, 1999 yılında profesyonel olarak adım attığı yazılım dünyasında, 2003 yılından beri Microsoft .Net teknolojileri ile ilgilenmektedir. Yazılım hayatına Assist Line isimli Call Center firmasında Delphi programcısı olarak başlayan Şenyurt sonrasında, sırasıyla Bizitek(Junior Developer), Netron(Master Trainer), Citibank(Outsource Senior Software Developer), Innova(Application Development Consultant), ve TCM(Software Architect) firmalarında görev almıştır. Su anda ING Bank bünyesinde Kıdemli Yazılım Danışmanı olarak görev yapmaktadir. 2006, 2007 yıllarında C#, 2008,2009,2010 yıllarında ise Connected System Developer kategorisinde Microsoft MVP seçilen Şenyurt, evli ve 1 çocuk babasıdır. C# diline olan düşkünlüğü, oğluna S(h)arp adının verilmesinde önemli bir etken olmustur.

Sosyal Medya

ORANLAR

  • 9139izleme

Arkadaşlarınla Paylaş

  • Tweet

0 Yorum

Yorum Yaz / Soru Sor

Lütfen yorum yazmak veya soru sormak için üye girişi yapınız.

Son Yorumlar

  • Hocam Link başka sayfaya yönlendiriyor.
  • merhaba benim merak ettiğim bir konu var y...
  • Merhaba download linki çalışmıyor. Rica et...
  • Nevzat Bey selamlar, Açıkçası bizler a...
  • Parametreleri Cache İşleminden Yalıtma kon...

En Güncel Sorular

  • Bilgilendirme maili (C#.Net)
  • Power Pivot (Sharepoint 2010)
  • BigInteger, BigDecimal (Asp.Net ve Asp.Net MVC)
  • visual C# ile asp nette veritabanı islemleri (Asp.Net ve Asp.Net MVC)
  • Share Point ile Dosya Arşiv Yönetim Sistemi yapılabilir mi ? (Sharepoint 2010)

En Son Cevap Verilen Sorular

  • Bilgilendirme maili
  • BigInteger, BigDecimal
  • visual C# ile asp nette veritabanı islemleri
  • Share Point ile Dosya Arşiv Yönetim Sistemi yapılabilir mi ?
  • txt dosyasına veri yazma

Twitter

Takip et: @yazilim_dilleri

En Çok Okunanlar

Elif BAYRAKDAR

C# ile SQL Server Bağlantısı, Insert, Update ve Delete Sorguları

23.05.2013

  • 120172
  • 0
Hakan Keskin

C# ile Windows Service Projesi Oluşturma, Debug Etme ve Setup Hazırlama

17.12.2013

  • 65293
  • 0
batuhan avlayan

Php - Mail Gönderme (İletişim Formu)

02.09.2013

  • 48406
  • 0

Sponsorlar

KODLAB
Pluralsight
Exchange server is
Office 365
YAZILIM DİLLERİ
Yukarı Çık
  • Hakkımızda
  • Facebook
  • Twitter
  • RSS

© Yazılım Dillerinin Buluşma Noktası | Kaynak belirtildiği sürece makaleler kopyalanabilir.
YazilimDilleri.Net sitesinde yer alan kullanıcıların oluşturduğu tüm içeriklerin yayınlanması ile ilgili yasal yükümlülükler içeriği oluşturan kullanıcıya aittir, YazilimDilleri.Net hiçbir şekilde sorumlu değildir.

Kapat

Giriş Yap

Kullanıcı Adı

Şifre

Şifremi Unuttum

KULLANICI GİRİŞİ