4 Mayıs 2015 Pazartesi

C# Notlarım

Access Modifier
Programlama Dillerinde Access Modifier başlıklı yazıya taşıdım.

Anonim Sınıflar
Anonymous subclass veya Anonymous Types olarak ta bilinirler. Anonim sınıfların hepsi object'ten kalıtırlar. Başka bir sınıftan kalıtmak mümkün değildir.

Auto Property
Auto Property yazısına taşıdım.

const
const sadece literal değerleri ve string için kullanılabilir. reference type için kullanılamaz. Aşağıdaki örnek derleme hatası verir.
public const StringBuilder BarBuilder = new StringBuilder();
Açıklaması şöyle

when the compiler encounters a constant identifier in C# source code (for example, months), it substitutes the literal value directly into the intermediate language (IL) code that it produces. Because there is no variable address associated with a constant at run time, const fields cannot be passed by reference and cannot appear as an l-value in an expression.
Exception
C# dilinde exception'lar hep birbirlerini sarmalayacak şekilde kullanılıyor. Sebebi ise üst katmanlara doğru çıktıkça alttaki detaylı SQLException yerine StorageException şeklinde daha genel bir hataların kullanılması. Böylece üst katman altta veritabanı yerine başka bir teknoloji kullanılsa bile etkilenmiyor.

Exception Filter
C# 6.0 ile gelen bu özellik sayesinde exception'ı yakalayıp içine bakmak gerekmiyor.
Örnek
catch (Win32Exception exception) if (exception.NativeErrorCode == 0x00042)  
{  
    //Do something here 
}  

Explicit Interface
Arayüz'den kalıtan sınıf arayüzün gerektirdiği metodları saklar. Böylece arayüzün gerektirdiği gibi her metod veya field'ın public olmasının önüne geçilebilir. Arayüzden gelen metod veya field'ı kullanabilmek için sınıfı arayüze cast edip kullanmak gerekir.
Örnek:

interface IFoo
{
   void Foo();
}

class FooImplementation : IFoo
{
   void IFoo.Foo()
   {
   }
}
Event
Konuyu Observer ve Observable başlıklı yazıya taşıdım.

Identifier
Değişken isimleri CamelCase'dir. Eğer bir keyword değişken ismi olarak kullanılmak istenirse aşağıdaki gibi yapılabilir.
int @private = 15;

Interface
C# Hungarian gösterime pek uymasa da arayüzlerde kullanmıştır. Tüm arayüzler I harfi ile başlar.

Interface ve Property
Interface bir property tanımlayabilir. Kalıtan her sınıfın da bu property alanını tanımlaması gerekir.
interface I{
    int property{get;set;}
}

Private Interface
Private Interface kullanarak bazı kodları aynı assembly içinde olsa bile saklamak mümkün.
public class MyClass
{
    private interface IFoo
    {
     int MyProp { get; }
    }

    public class Foo : IFoo
    {
     int IFoo.MyProp { get; set; }
    }

    public static void Main(string[] args)
    {
     IFoo foo = new Foo();
     return foo.MyProp;
    }
}

public class HiddenFromMe
{
    public static void Main(string[] args)
    {
     MyClass.Foo foo = new MyClass.Foo();
     return foo.MyProp; // fails to compile
    }
}

Keyword
C#'ta anahtar kelimeler normal keyword ve contextual keyword olarak ikiye ayrılıyor. Normal keyword'lerin tanımı şöyle:

Keywords are predefined, reserved identifiers that have special meanings to the compiler.

Contextual keyword'lerin tanımı ise şöyle
contextual keyword is used to provide a specific meaning in the code, but it is not a reserved word in C#.

Contextual keyword'ler aynı kelimenin nerede kullanıldığına göre anlam kazanır. Örnekte new kelimesi hem nesne yaratmak hem de metodun virtual özelliğini değiştirmek için kullanılıyor.
//One situation for create an instance of class:
StringBuilder sr=new StringBuilder();

//Another situation for method hiding in polymorphism subject of OOP:
public new void Foo()
{
   //Some Code
}

Lambda
Lambda'yı saklamak için Function sınıfı kullanılabilir.
Func<bool> anyCarDoesNotHaveDoor = () => { 
    foreach(var car in cars)
       if (car.door == null)
           return true;
    return false; 
};

if (anyCarDoesNotHaveDoor())
   // then ...
Lambda local değişkenleri ve global değişkenleri farklı yakalıyor. Örnekte her bir lambda'da local değişkenin kopyası saklanıyor.
static void Main(string[] args)
{
    Action x1 = GetWorker(0);
    Action x2 = GetWorker(1);
}

static Action GetWorker(int k)
{
    int count = 0;

    // Each Action delegate has it's own 'captured' count variable
    return k == 0 ? (Action)(() => Console.WriteLine("Working 1 -{0}",count++))
                  : (Action)(() => Console.WriteLine("Working 2 -{0}",count++));
}
Eğer üretilen lamdanın ismini Counter kabul edersek sanki aşağıdakine benzer bir lambda kodu üretiliyor.
class Counter { public int count; }
Ama global bir değişken capture edilirse her lambda aynı değişkeni kullanıyor.
static int count = 0;

static Action GetWorker(int k)
{
    return k == 0 ? (Action)(() => Console.WriteLine("Working 1  {0}",count++))
                  : (Action)(() => Console.WriteLine("Working 2  {0}",count++));
}

Namespace
C#'ta namespace hiyerarşiktir. Bir namespace'ten kalıtan alt namespace, kalıttığı namespace içindeki sınıfları görebilir. Burada kalıtım tabirini nemspace'lerin iç içe olduklarını belirtmek için mecazi anlamda kullandım.

Named Arguments veya Named Parameters
Posizyon ile verilen parametrelerden sonra Named Arguments kullanılabilir. Named argument için önce parametre adı sonra iki nokta üstüste kullanılıyor. Örnek'te fontColour ve fontFamily isim ile geçilmiş
myMethod("SomeString" , fontColour: "blue", fontFamily: "Tahoma")
Named Arguments genellikle fazla sayıda parametre alan metodlarda okunulurluğu artırmak için kullanılıyor. Eğer parametre sayısı çok fazla ise Named Arguments ta okunurluğu sağlamayabilir. Bu durumda bir diğer seçenek Fluent Interface'leri denemek olabilir. Örnekte üç parametre geçiliyor.
func DrawRectangleClipped (rectToDraw, fillColor, clippingRect) {}
Benzer bir kod fluent yöntemle aşağıdaki gibi yazılabilirdi.
something.draw(new Box().withHeight(5).withWidth(20))

Null Coalescing (null birleştirme)
Konuyu diğer programlama dilleri ile karşılaştırmak için Coalesce başlıklı yazıya taşıdım.

Operator
Implicit ve Explicit operator bulunur. Implicit operator sınıfımıza değer atamak için kullanılır. Explicit operator ise C++'taki conversion operator'e benziyor. Örnek:
public static implicit operator Money(decimal money)
{
    return new Money(money);
}

public static explicit operator decimal(Money money)
{
    return money._value;
}
Override
Override virtual tanımlanan bir metodu tekrar tanımlamak için kullanılır. Java'nın tersine her metod virtual olmadığı için virtual + override kelimelerine ihtiyaç vardır.

new kelimesi ise virtual olmayan bir metodu bir sınıfa mahsus olarak değiştirmek yani bir nevi için bulunur. Kullanılmasını kesinlikle tavsiye etmem.

Preprocessor
C# ile C++'taki gibi preprocessor tanımlanabilir. Ancak C++'taki gibi Macro tanımlanamaz.



Ref
ref ile beraber kullanılan parametre bir nesne ise nesnenin bir başka nesneye atanabilmesini sağlar.
"It allows the method to reassign the pointer to a new object". Örnek
public void Foo (ref ArrayList list)
{
  list = new ArrayList(){"test"};
}

Eğer ref ile beraber kullanılan parametre bir value type ise, metod içinde yapılan değişkliğin dışarıya aktarılabilmesini sağlar.

Out ile ref'in tek farkı out parametrenin ilk değerinin atanmış olmasını şart koşmaz.


Switch/Case
C#'ta Delphi'deki gibi aralık verilemiyor!
Case Total of
    80..100 : ShowMessage ('You got an A!');
    60..79  : ShowMessage ('You got a B!');
    50..59  : ShowMessage ('You got a C!');
    40..49  : ShowMessage ('You got a D!');
    0..39   : ShowMessage ('You got an E...'); 

Var Anahtar Kelimesi
statically typed dillerde hem explicit hem de implicit kullanım var. var kelimesi implicit alt kümesine giriyor. Aynı kullanımı C++'ta auto ile de görebiliriz.

var anahtar kelimesi compile time'da atama işleminin sağ tarafına bakara kullanılacak tipi belirler.
Dolayısıyla aşağıdaki örnek derleme hatası verir.
var variable_name = new class_a(); // there is no error and is working fine

var variable_name; 
variable_name = new class_a(); // this line is throwing error
Veri Yapıları
Dictionary
OrderedDictionary veriyi tree gibi sıralı tutar.

Thread Safe Veri Yapıları
Bu sınıflar System.Collections.Concurrent altında bulunuyor
BlockingCollection
ConcurrentBag
ConcurrentDictionary
ConcurrentDictionary
ConcurrentQueue
ConcurrentStack


Hiç yorum yok:

Yorum Gönder