C# ve .NET [8]

Giriş: Kod Okyanusunda Organizasyon İhtiyacı Küçük bir C# programı yazdığımızda, tüm sınıflarımızı ve diğer türlerimizi tek bir dosyada veya birkaç dosyada global alanda tanımlamak yeterli olabilir. Ancak projeler büyüdükçe, yüzlerce hatta binlerce sınıf, yapı, arayüz vb. içermeye başladığında işler hızla karmaşıklaşır. İsim Alanları Olmasaydı Karşılaşılacak Sorunlar: İsim Çakışmaları (Naming Collisions): En büyük sorun budur. Farklı geliştiriciler veya farklı kütüphaneler, aynı amaç için olmasa bile, aynı isimde sınıflar veya türler tanımlayabilir. Örneğin, hem sizin projenizde hem de kullandığınız bir üçüncü parti kütüphanede Logger adında bir sınıf olabilir. İsim alanları olmadan, derleyici hangi Logger sınıfını kullanacağını bilemez ve bu bir derleme hatasına veya daha kötüsü, çalışma zamanında beklenmedik davranışlara yol açar. Tüm türlerin benzersiz isimlere sahip olması gerekirdi ki bu büyük projelerde neredeyse imkansızdır. Kod Organizasyonu Eksikliği: Tüm türler tek bir “global” alanda bulunduğunda, mantıksal olarak ilişkili sınıfları bir arada gruplamak zorlaşır. Projenin yapısını anlamak, belirli bir işlevselliğe ait sınıfları bulmak ve kodu yönetmek giderek zorlaşır. Kod tabanı “düz” ve kaotik bir hal alır. Yönetilebilirlik ve Bakım Zorluğu: İsim çakışmaları ve organizasyon eksikliği, kodun bakımını yapmayı, yeni özellikler eklemeyi veya mevcut kodu yeniden düzenlemeyi (refactoring) çok daha zor ve riskli hale getirir. İşte bu noktada İsim Alanları (Namespaces) devreye girer. Tıpkı bilgisayarımızdaki dosyaları anlamlı klasörler içinde organize etmemiz gibi, isim alanları da kodumuzu mantıksal hiyerarşik gruplara ayırmamızı sağlar. İsim Alanlarının Amaçları: Organizasyon: İlişkili türleri (sınıflar, struct’lar, interface’ler, enum’lar, delegate’ler) mantıksal gruplar altında toplamak. Örneğin, tüm kullanıcı arayüzü ile ilgili sınıflar MyProject.UI isim alanında, veri erişim sınıfları MyProject.DataAccess isim alanında olabilir. İsim Çakışmalarını Önleme: Türlere tam nitelikli (fully qualified) bir isim vererek ( NamespaceAdi.SinifAdi ) aynı isme sahip farklı türlerin birbirinden ayırt edilmesini sağlamak. MyProject.Logging.Logger ile ThirdPartyLib.Logging.Logger farklı türler olarak ele alınır. Erişim Kontrolü (Dolaylı): internal erişim belirleyicisi ile birlikte kullanıldığında, bir türün sadece kendi derlemesi (assembly) içindeki aynı isim alanından veya farklı isim alanlarından erişilebilir olmasını sağlar (ancak isim alanları doğrudan erişim kontrolü mekanizması değildir, erişim belirleyiciler bu işi yapar). Kodun Kapsamını Belirleme: Bir türün hangi mantıksal gruba ait olduğunu netleştirir. Bölüm 1: İsim Alanı Tanımlama (namespace Anahtar Kelimesi) C#’ta bir isim alanı tanımlamak için namespace anahtar kelimesi kullanılır, ardından isim alanına bir ad verilir ve bu isim alanına ait olacak türler kıvırcık parantezler {} içine alınır. Sözdizimi: namespace IsimAlaniAdi { // Bu isim alanına ait sınıflar, struct'lar, interface'ler, enum'lar, delegeler class BenimSinifim { // ... } struct BenimYapim { // ... } interface IBenimArayuzum { // ... } // ... diğer türler } namespace: İsim alanı tanımını başlatan anahtar kelime. IsimAlaniAdi: İsim alanına verilen addır. Genellikle şirket adı, proje adı ve ardından modül veya katman adını içeren hiyerarşik bir yapı kullanılır ve noktalarla (.) ayrılır (örn. Microsoft.EntityFrameworkCore, System.Collections.Generic, MyCompany.MyProject.BusinessLogic). Adlandırmada PascalCase kuralı kullanılır. { … }: İsim alanının kapsamını belirleyen bloktur. Bu blok içindeki tüm türler o isim alanına aittir. Örnek: // Dosya: Models/Musteri.cs namespace ECommerceApp.Models { public class Musteri { public int Id { get; set; } public string AdSoyad { get; set; } // ... diğer özellikler } } // Dosya: Models/Urun.cs namespace ECommerceApp.Models // Aynı isim alanı farklı dosyalarda tanımlanabilir { public class Urun { public int UrunId { get; set; } public string UrunAdi { get; set; } public decimal Fiyat { get; set; } } } // Dosya: Services/SiparisService.cs namespace ECommerceApp.Services { // Başka bir isim alanı using ECommerceApp.Models; // Models isim alanını kullanacağımızı belirtiyoruz (using direktifi) public class SiparisService { public void SiparisOlustur(Musteri musteri, List urunler) { Console.WriteLine($"{musteri.AdSoyad} için sipariş oluşturuluyor..."); foreach (var urun in urunler) { Console.WriteLine($"- {urun.UrunAdi}"); } // ... sipariş oluşturma mantığı ... } } } Dosya Kapsamlı İsim Alanları (File-Scoped Namespaces — C# 10+) C# 10 ile birlikte, bir dosyadaki tüm türlerin tek bir isim alanına ait olacağı durumlarda daha kısa bir söz dizimi gelmiştir. namespace tanımı dosyanın en başına yazıl

Apr 9, 2025 - 11:27
 0
C# ve .NET [8]

Giriş: Kod Okyanusunda Organizasyon İhtiyacı

Küçük bir C# programı yazdığımızda, tüm sınıflarımızı ve diğer türlerimizi tek bir dosyada veya birkaç dosyada global alanda tanımlamak yeterli olabilir. Ancak projeler büyüdükçe, yüzlerce hatta binlerce sınıf, yapı, arayüz vb. içermeye başladığında işler hızla karmaşıklaşır.

İsim Alanları Olmasaydı Karşılaşılacak Sorunlar:

İsim Çakışmaları (Naming Collisions): En büyük sorun budur. Farklı geliştiriciler veya farklı kütüphaneler, aynı amaç için olmasa bile, aynı isimde sınıflar veya türler tanımlayabilir. Örneğin, hem sizin projenizde hem de kullandığınız bir üçüncü parti kütüphanede Logger adında bir sınıf olabilir. İsim alanları olmadan, derleyici hangi Logger sınıfını kullanacağını bilemez ve bu bir derleme hatasına veya daha kötüsü, çalışma zamanında beklenmedik davranışlara yol açar. Tüm türlerin benzersiz isimlere sahip olması gerekirdi ki bu büyük projelerde neredeyse imkansızdır.
Kod Organizasyonu Eksikliği: Tüm türler tek bir “global” alanda bulunduğunda, mantıksal olarak ilişkili sınıfları bir arada gruplamak zorlaşır. Projenin yapısını anlamak, belirli bir işlevselliğe ait sınıfları bulmak ve kodu yönetmek giderek zorlaşır. Kod tabanı “düz” ve kaotik bir hal alır.
Yönetilebilirlik ve Bakım Zorluğu: İsim çakışmaları ve organizasyon eksikliği, kodun bakımını yapmayı, yeni özellikler eklemeyi veya mevcut kodu yeniden düzenlemeyi (refactoring) çok daha zor ve riskli hale getirir.
İşte bu noktada İsim Alanları (Namespaces) devreye girer. Tıpkı bilgisayarımızdaki dosyaları anlamlı klasörler içinde organize etmemiz gibi, isim alanları da kodumuzu mantıksal hiyerarşik gruplara ayırmamızı sağlar.

İsim Alanlarının Amaçları:

Organizasyon: İlişkili türleri (sınıflar, struct’lar, interface’ler, enum’lar, delegate’ler) mantıksal gruplar altında toplamak. Örneğin, tüm kullanıcı arayüzü ile ilgili sınıflar MyProject.UI isim alanında, veri erişim sınıfları MyProject.DataAccess isim alanında olabilir.
İsim Çakışmalarını Önleme: Türlere tam nitelikli (fully qualified) bir isim vererek ( NamespaceAdi.SinifAdi ) aynı isme sahip farklı türlerin birbirinden ayırt edilmesini sağlamak. MyProject.Logging.Logger ile ThirdPartyLib.Logging.Logger farklı türler olarak ele alınır.
Erişim Kontrolü (Dolaylı): internal erişim belirleyicisi ile birlikte kullanıldığında, bir türün sadece kendi derlemesi (assembly) içindeki aynı isim alanından veya farklı isim alanlarından erişilebilir olmasını sağlar (ancak isim alanları doğrudan erişim kontrolü mekanizması değildir, erişim belirleyiciler bu işi yapar).
Kodun Kapsamını Belirleme: Bir türün hangi mantıksal gruba ait olduğunu netleştirir.
Bölüm 1: İsim Alanı Tanımlama (namespace Anahtar Kelimesi)

C#’ta bir isim alanı tanımlamak için namespace anahtar kelimesi kullanılır, ardından isim alanına bir ad verilir ve bu isim alanına ait olacak türler kıvırcık parantezler {} içine alınır.

Sözdizimi:

namespace IsimAlaniAdi
{
// Bu isim alanına ait sınıflar, struct'lar, interface'ler, enum'lar, delegeler
class BenimSinifim
{
// ...
}
struct BenimYapim
{
// ...
}
interface IBenimArayuzum
{
// ...
}
// ... diğer türler
}
namespace: İsim alanı tanımını başlatan anahtar kelime.
IsimAlaniAdi: İsim alanına verilen addır. Genellikle şirket adı, proje adı ve ardından modül veya katman adını içeren hiyerarşik bir yapı kullanılır ve noktalarla (.) ayrılır (örn. Microsoft.EntityFrameworkCore, System.Collections.Generic, MyCompany.MyProject.BusinessLogic). Adlandırmada PascalCase kuralı kullanılır.
{ … }: İsim alanının kapsamını belirleyen bloktur. Bu blok içindeki tüm türler o isim alanına aittir.
Örnek:

// Dosya: Models/Musteri.cs
namespace ECommerceApp.Models
{
public class Musteri
{
public int Id { get; set; }
public string AdSoyad { get; set; }
// ... diğer özellikler
}
}
// Dosya: Models/Urun.cs
namespace ECommerceApp.Models // Aynı isim alanı farklı dosyalarda tanımlanabilir
{
public class Urun
{
public int UrunId { get; set; }
public string UrunAdi { get; set; }
public decimal Fiyat { get; set; }
}
}
// Dosya: Services/SiparisService.cs
namespace ECommerceApp.Services
{
// Başka bir isim alanı
using ECommerceApp.Models; // Models isim alanını kullanacağımızı belirtiyoruz (using direktifi)
public class SiparisService
{
public void SiparisOlustur(Musteri musteri, List urunler)
{
Console.WriteLine($"{musteri.AdSoyad} için sipariş oluşturuluyor...");
foreach (var urun in urunler)
{
Console.WriteLine($"- {urun.UrunAdi}");
}
// ... sipariş oluşturma mantığı ...
}
}
}
Dosya Kapsamlı İsim Alanları (File-Scoped Namespaces — C# 10+)

C# 10 ile birlikte, bir dosyadaki tüm türlerin tek bir isim alanına ait olacağı durumlarda daha kısa bir söz dizimi gelmiştir. namespace tanımı dosyanın en başına yazılır ve noktalı virgülle bitirilir; kıvırcık parantezlere gerek kalmaz. Bu, gereksiz girintilemeyi azaltır.

// Dosya: Models/Adres.cs (C# 10+)
namespace ECommerceApp.Models; // Dosya kapsamlı namespace
public class Adres
{
public string Sokak { get; set; }
public string Sehir { get; set; }
}
// Bu dosyadaki diğer tüm türler de ECommerceApp.Models içinde kabul edilir.
// class PostaKodu { ... }
İç İçe İsim Alanları (Nested Namespaces)

İsim alanları daha fazla organizasyon sağlamak için iç içe tanımlanabilir.

namespace FirmaAdi.ProjeAdi
{
namespace KullaniciArayuzu // İç içe isim alanı
{
public class AnaPencere { /* ... / }
}
namespace VeriErisim // İç içe başka bir isim alanı
{
public class VeritabaniBaglantisi { /
... / }
}
}
// Veya daha kısa nokta (.) notasyonu ile:
namespace FirmaAdi.ProjeAdi.IsMantigi
{
public class HesaplamaServisi { /
... */ }
}
Bu yapı, türleri daha granüler bir şekilde gruplandırmayı sağlar.

Bölüm 2: İsim Alanlarını Kullanma (using Direktifi)

Başka bir isim alanında tanımlanmış bir türü (sınıf, struct vb.) kullanmak istediğimizde, her seferinde tam nitelikli adını ( IsimAlani.AltIsimAlani.SinifAdi ) yazmak yerine, kodun başına using direktifini ekleyebiliriz.

2.1. using Direktifi:

Amacı: Belirli bir isim alanını mevcut dosyanın kapsamına dahil eder. Bu sayede, o isim alanındaki türleri sadece kendi adlarıyla (tam nitelikli ad olmadan) kullanabiliriz.
Söz Dizimi: using IsimAlaniAdi;
Yerleşim: Genellikle C# dosyasının en başında, namespace tanımından önce (veya dosya kapsamlı namespace kullanılıyorsa ondan sonra) yer alır.
Örnek (Yukarıdaki örneğe devam):

// Dosya: Program.cs
using System;
using System.Collections.Generic; // List sınıfını kullanmak için
using ECommerceApp.Models; // Musteri ve Urun sınıflarını kullanmak için
using ECommerceApp.Services; // SiparisService sınıfını kullanmak için
namespace ECommerceApp.ConsoleUI
{
class Program
{
static void Main(string[] args)
{
// using direktifleri sayesinde tam isimleri yazmaya gerek kalmaz:
Musteri musteri1 = new Musteri { Id = 1, AdSoyad = "Ahmet Yılmaz" };
Urun urun1 = new Urun { UrunId = 101, UrunAdi = "Laptop", Fiyat = 15000m };
Urun urun2 = new Urun { UrunId = 102, UrunAdi = "Klavye", Fiyat = 500m };
List sepet = new List { urun1, urun2 };
SiparisService siparisServisi = new SiparisService();
siparisServisi.SiparisOlustur(musteri1, sepet);
// Eğer using ECommerceApp.Models; olmasaydı:
// ECommerceApp.Models.Musteri musteri1 = new ECommerceApp.Models.Musteri { ... };
// şeklinde yazmak gerekirdi.
}
}
}
2.2. İsim Çakışması Durumunda Tam Nitelikli Ad Kullanımı:

Eğer iki farklı isim alanından aynı isimde bir türü using ile dahil ettiyseniz (veya bir tür lokal kapsamdaki bir değişkenle aynı isme sahipse), derleyici hangi türü kullanacağını bilemez ve bir belirsizlik hatası verir. Bu durumda, çakışan türü kullanırken tam nitelikli adını (fully qualified name) yazmanız gerekir.

using System.Timers; // Timer sınıfı var
using System.Threading; // Timer sınıfı var
namespace CakismaninCozumu
{
class Test
{
void Calistir()
{
// Timer t; // HATA! Hangi Timer? System.Timers.Timer mı, System.Threading.Timer mı?
// Çözüm: Tam nitelikli ad kullan
System.Timers.Timer timer1 = new System.Timers.Timer();
System.Threading.Timer timer2 = new System.Threading.Timer(callback => {}, null, 0, 1000);
Console.WriteLine("Timerlar oluşturuldu.");
}
}
}
Bölüm 3: using Direktifinin Gelişmiş Kullanımları

3.1. İsim Alanı Takma Adları (Namespace Aliases)

Uzun veya iç içe geçmiş isim alanlarını kısaltmak veya yukarıdaki gibi isim çakışmalarını daha zarif bir şekilde çözmek için using direktifi ile bir takma ad (alias) tanımlanabilir.

Söz Dizimi:

using TakmaAd = Tam.Nitelikli.Isim.AlaniAdi;
using TakmaTipAdi = Tam.Nitelikli.Isim.AlaniAdi.TipAdi;
Örnek:

using System;
using TimerThread = System.Threading.Timer; // System.Threading.Timer için takma ad
using TimerEvents = System.Timers.Timer; // System.Timers.Timer için takma ad
using Utilities = MyCompany.MyProject.Common.Utilities; // Uzun isim alanı için takma ad
namespace TakmaAdKullanimi
{
class Test
{
void Calistir()
{
TimerThread t1 = new TimerThread(callback => {}, null, 0, 1000);
TimerEvents t2 = new TimerEvents(5000);
string logMesaji = Utilities.LogFormatter.Format("İşlem başladı");
Console.WriteLine("Takma adlarla oluşturuldu.");
}
}
// Başka bir dosyadaki namespace'e aitmiş gibi varsayalım
namespace MyCompany.MyProject.Common.Utilities
{
public static class LogFormatter
{
public static string Format(string msg) => $"[{DateTime.Now:T}] {msg}";
}
}
}
Takma adlar, özellikle çakışma durumlarında veya çok uzun isim alanlarıyla çalışırken kodun okunabilirliğini önemli ölçüde artırabilir.

3.2. Statik using Direktifi (Static using — C# 6+)

Bir sınıfın statik üyelerine (metotlar, özellikler, alanlar), sınıf adını yazmadan doğrudan erişebilmenizi sağlar. Özellikle sık kullanılan statik yardımcı sınıflar (Math, Console, string, Enumerable vb.) için kullanışlıdır.

Söz Dizimi:

using static System.Math;
using static System.Console;
using static System.Linq.Enumerable; // LINQ metotları için
Örnek:

using System;
using static System.Console; // Console sınıfının statik üyeleri için
using static System.Math; // Math sınıfının statik üyeleri için
using System.Collections.Generic;
using System.Linq;
using static System.Linq.Enumerable; // Range gibi metotlar için
namespace StatikUsingKullanimi
{
class Program
{
static void Main(string[] args)
{
// Console.WriteLine yerine doğrudan WriteLine
WriteLine("Statik using örneği!");
// Math.PI yerine doğrudan PI
double cevre = 2 * PI * 5;
// Math.Sin yerine doğrudan Sin
double sinusDegeri = Sin(PI / 2);
WriteLine($"Çevre: {cevre:F2}");
WriteLine($"Sin(PI/2): {sinusDegeri}");
List sayilar = new List { 1, 2, 3, 4, 5 };
// System.Linq.Enumerable.Where yerine doğrudan Where (using static ile)
var ciftSayilar = sayilar.Where(n => n % 2 == 0);
// System.Linq.Enumerable.Range yerine doğrudan Range
var ilkOnSayi = Range(1, 10);
foreach (var sayi in ciftSayilar)
{
Write(sayi + " "); // WriteLine yerine Write
}
WriteLine(); // Yeni satır
foreach (var sayi in ilkOnSayi)
{
Write(sayi + " ");
}
WriteLine();
}
}
}
Statik using, kodu kısaltabilir ancak aşırı kullanımı hangi metodun hangi sınıftan geldiğini belirsizleştirerek okunabilirliği azaltabilir. Genellikle Math, Console gibi çok temel ve sık kullanılan sınıflar için tercih edilir.

3.3. Global using Direktifleri (Global using — C# 10+)

C# 10 ile gelen bu özellik, bir using direktifinin projenin tüm dosyaları için geçerli olmasını sağlar. Bu, her dosyada tekrar tekrar aynı using ifadelerini yazma ihtiyacını ortadan kaldırır.

Genellikle projenin kök dizininde ayrı bir dosyada (örn. GlobalUsings.cs) veya .csproj dosyasında tanımlanır.
global anahtar kelimesi using’in başına eklenir.
Örnek (GlobalUsings.cs):

// Bu direktifler projedeki tüm C# dosyaları için geçerli olacak
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
global using ECommerceApp.Models; // Kendi isim alanlarımızı da global yapabiliriz
global using static System.Console; // Global statik using de mümkün
Bu özellik, özellikle her dosyada standart olarak kullanılan System, System.Collections.Generic, System.Linq gibi isim alanları için kod tekrarını azaltır ve dosyaları daha temiz hale getirir.

Bölüm 4: İsim Alanları ve Derlemeler (Assemblies)

Derleme (Assembly): .NET’te derlenmiş kodun (genellikle bir .dll veya .exe dosyası) dağıtım birimidir. Bir veya daha fazla isim alanı içerebilir.
internal Erişim Belirleyicisi: internal olarak işaretlenen türler veya üyeler, sadece tanımlandıkları aynı derleme içindeki kod tarafından erişilebilir. İsim alanları, internal ile birlikte bir derlemenin iç uygulama detaylarını dış dünyadan gizlemek için kullanılabilir. Farklı bir derlemeden (farklı proje) o internal türe erişilemez.
Bölüm 5: En İyi Uygulamalar ve Adlandırma Kuralları

Hiyerarşik ve Anlamlı İsimlendirme: İsim alanlarınızı mantıksal bir hiyerarşiyle (genellikle SirketAdi.ProjeAdi.KatmanAdi veya SirketAdi.UrunAdi.OzellikAlani gibi) ve açıklayıcı isimlerle oluşturun. Bu, projenin yapısını anlamayı kolaylaştırır.
Klasör Yapısını Yansıtma: Genellikle, isim alanı yapısının projenizdeki klasör yapısını yansıtması önerilir. Örneğin, ECommerceApp.Models isim alanındaki sınıflar projenin Models klasöründe bulunur. Bu, kodda gezinmeyi kolaylaştırır. Visual Studio gibi IDE’ler genellikle bu yapıyı otomatik olarak oluşturur.
using Direktiflerini Başta Tutma: using direktiflerini C# dosyasının en başına yerleştirin. Bu, dosyanın hangi dış bağımlılıklara sahip olduğunu bir bakışta görmeyi sağlar.
Gereksiz using’lerden Kaçınma: Kullanılmayan using direktiflerini temizleyin. IDE’ler genellikle bunun için otomatik araçlar sunar.
Tam Nitelikli Adları Sadece Gerektiğinde Kullanma: İsim çakışması olmadıkça using direktiflerini tercih edin. Tam nitelikli adlar kodu daha uzun ve okunaksız hale getirebilir.
Takma Adları (Aliases) Dikkatli Kullanma: Takma adlar çakışmaları çözmek veya çok uzun isimleri kısaltmak için kullanışlıdır, ancak aşırı veya anlamsız takma ad kullanımı kodu kafa karıştırıcı hale getirebilir.
Statik using’i Ölçülü Kullanma: Sadece çok sık kullanılan ve kaynağı belli olan statik sınıflar (Console, Math) için kullanın. Aşırı kullanım okunabilirliği azaltabilir.
Global using’leri Akıllıca Kullanma: Projenin genelinde kullanılan standart isim alanları için global using harikadır, ancak çok fazla veya çok spesifik isim alanını global yapmak, isim çakışması riskini artırabilir ve hangi dosyanın neye bağımlı olduğunu anlamayı zorlaştırabilir. Genellikle temel .NET isim alanları ve projenin kendi ana isim alanları için kullanılır.
Bölüm 6: Sonuç — Kodun GPS’i

İsim Alanları (Namespaces), C# ve .NET ekosisteminde kod organizasyonunun temelini oluşturur. Onlar olmadan, büyük ölçekli yazılım geliştirmek neredeyse imkansız hale gelirdi. İsim çakışmalarını önleyerek, kodu mantıksal olarak gruplandırarak ve projenin yapısını netleştirerek geliştiricilere büyük faydalar sağlarlar.

namespace anahtar kelimesi ile tanımlanır, hiyerarşik yapılar oluşturulabilir ve C# 10 ile gelen dosya kapsamlı isim alanları söz dizimini basitleştirir. using direktifi, başka isim alanlarındaki türlere kolayca erişmemizi sağlar. İsim çakışmalarını çözmek veya okunabilirliği artırmak için tam nitelikli adlar, takma adlar (using Alias = …) ve statik using (using static …) gibi araçlar sunulur. C# 10'un global using direktifleri ise proje genelindeki standart using tekrarlarını azaltır.

İyi tasarlanmış bir isim alanı yapısı, projenin anlaşılabilirliğini, yönetilebilirliğini ve bakım kolaylığını doğrudan etkiler. Tıpkı iyi organize edilmiş bir dosya sistemi gibi, iyi organize edilmiş isim alanları da kod okyanusunda yolumuzu bulmamızı sağlayan bir GPS görevi görür. Bu nedenle, C# ile geliştirme yaparken isim alanlarını doğru ve tutarlı bir şekilde kullanmak, profesyonel yazılım geliştirmenin temel bir gerekliliğidir.

Abdulkadir Güngör - Kişisel WebSite
Abdulkadir Güngör - Kişisel WebSite
Abdulkadir Güngör - Özgeçmiş
Github
Github
Linkedin