C# ile İlgili Sık Sorulan Sorular (SSS)

Bu yazıda C# dili ilgili sık sorulan sorulara yanıt verilmiştir.

Aşağıdaki C# ile ilgili sık sorulan sorular www.msdn.com adresinde faaliyet gösteren Microsoft Visual C# ekibi tarafından hazırlanmıştır.


S - 1
: DllImport niteliğini neden çalıştıramıyorum?

C - 1 : DllImport ile işaretlenen bütün metotlar public static extern olarak bildirilmelidir.



S - 2 : Yazdığım switch ifadeleri farklı bir biçimde çalışıyor. Neden?

C - 2 : C# case blokları için "explicit fall through" özelliğini desteklemez. Buna göre aşağıdaki kod parçası geçersizdir ve C#'ta derlenemez.

switch(x)
{
   case 0:
       // bir şeyler yap
   case 1:
       // 0 case'indekine ek olarak birşeyler daha yap
   default:
       // 0 ve 1 durumlarına ek olarak birşeyler daha yap
 
       break;
}

Yukarıdaki kodun verdiği etkiyi C# ile aşağıdaki gibi gerçekleştirrebiliriz. (Case' ler arasındaki akışın açıkça belirtildiğine dikkat edin!)

class Test
{
    public static void Main()
    {
        int x = 3;
 
        switch(x)
        {
            case 0:
                // bir şeyler yap
                goto case 1;
            case 1:
                // 0 case'indekine ek olarak birşeyler daha yap
                goto default;
            default:
                // 0 ve 1 durumlarına ek olarak birşeyler daha yap
                break;
        }
    }
}



S - 3
: const ve static readonly arasındaki farklar nelerdir?

C - 3 : static readonly elemanlar bulundukları sınıfın üye elemanları tarafından değiştirilebilir(!), fakat const olan üye elamanlar asla değiştirilemez ve derleme zamanı sabiti olarak ilk değerleri verilmelidir.

static readonly üye elemanlarının değiştirilebilmesini biraz açacak olursak, static readonly üyeyi içeren sınıf bu üyeyi aşağıdaki durumlarda değiştirebilir :

- değişken ilk değer verilen durumda
- static yapıcı metotlar içinde



S - 4
: trace ve asssert komutlarını nasıl gerçekleyebilirim?

C - 4 : Metotlarla birlikte Conditional niteliğini kullanarak gerçekleyebiliriz.

class Debug
{
    [conditional("TRACE")]
    public void Trace(string s)
    {
        Console.WriteLine(s);
    }
}
 
class MyClass
{
    public static void Main()
    {
        Debug.Trace("hello");
    }
}


Yukarıdaki örnekte Debug.Trace() metodu ancak ve ancak TRACE önişlemci seöbolü tanımlanmışsa çağrılacaktır. Komut satırından ön işlemci sembollerini tanımlamak için /D parametresi kullanılabilir. Conditional niteliği ile bildirilen metotların geri dönüş değerinin void olma zorunluluğu vardır.



S - 5
: C#'ta dll oluşturmak için ne yapmalıyım?

C - 5 : Derleyicinin /target:library argümanını kullanmanız gerekir.



S - 6
: checked isimli bir değişken tanımladığımda neden derleme zamanında "syntax error" hatası alıyorum?

C - 6 : Çünkü checked C#'ta bir anahtar sözcüktür.



S - 7
: Bir yapıcı metot içinde aşırı yüklenmiş başka bir yapıcı metot nasıl çağrılır (this() ve yapıcımetotadı() şeklindeki çağrımlar derlenmiyor)?

C - 7 : Diğer bir yapıcı metot aşağıdaki gibi çağrılabilir.

class B
{
    B(int i)
    {  }
}
 
class C : B
{
    C() : base(5)      //  B(5) i çağırır.
    {  }
 
    C(int i) : this()  //  C() yi çağırır.
    {  }
 
    public static void Main() {}
}

S - 8 : C#'ta Visual J++ ta bulunan instanceof operatörünün karşılığı varmıdır?

C - 8 : Evet, is operatörü bunun karşılığıdır. Kullanımı aşağıdaki gibidir :

          ifade is tür



S - 9
: C#'ta enum sabitleri nasıl kullanılır.

C - 9 : enum türlerinin kullanımına bir örnek :

namespace Foo
{
    enum Colors
    {
        BLUE,
        GREEN
    }
 
    class Bar
    {
        Colors color;
        Bar() { color = Colors.GREEN;}
        
        public static void Main() {}
    }
}



S - 10
: Geri dönüş değeri olmayan bir metot bildirimi yaptığımda neden (CS1006) hatası almaktayım?

C - 10 : Bir metodun geri dönüş değerini yazmadan bildirirseniz derleyici onu sanki bir yapıcı metot bildiriyormuşsunuz gibi davranır. O halde geri dönüş değeri olmayan bir metot bildirimi için void anahtar sözcüğünü kullanın. Aşağıda bu iki kullanıma örnek verilmiştir.

// Bu bildirim CS1006 hatası verir.
public static staticMethod (mainStatic obj)
 
// Bu metot ise istenildiği gibi çalışır.
public static void staticMethod (mainStatic obj)



S - 11
: Her birinde farklı Main() metodu olan birden fazla kaynak kod dosyam var: derleme sırasında hangi Main() metodunun kullanılacağını nasıl bildirebilirim?

C - 11 : Programınızın giriş noktası(metodu) Main isimli herhangi bir parametre almayan yada string türünden bir dizi parametresi alan geri dönüş değeri void yada int olan static bir metot olmalıdır.

C# derleyicisi programınızda birden fazla Main metodu bildirmenize izin verir fakat hangi Main() metodunu kullanacağınızı derleme zamanında bildirmeniz gerekir. Main() metodunu belirtirken Main metodunun bulunduğu sınıfın tam yolunu belirtmeniz gerekir. Komut satırından kullanılan /main argümanı bu işe yarar.(Örn : csc /main:MainSınıfı *.cs)



S - 12
: Console.WriteLine() metodu bir string içinde NULL karakteri gördüğünde ekrana yazma işlemini durdururmu?

C - 12 : Çalışma zamanı için string türleri NULL ile sonlandırılmış türler değildir. Dolayısıyla bir string içine NULL karakteri gömebilirsiniz. Console.WriteLine() ve buna benzer metotlar string değişkeninin sonuna kadar işlem yaparlar.



S - 13
: C# ta "Multicast Delegate"(çoklu temsilciler) bildirmek mümkünmüdür, mümkünse sentaksı nasıldır?

C - 13 : Bütün temsilciler varsayılan olarak multicast olarak bildirilir. Dolayısıyla Visual J++ taki gibi ayrıca multicast anahtar sözcüğü yoktur.



S - 14
: Delegate/MulticastDelegate (Temsilciler) nasıl bildirilir?

C - 14 : C# ta temsilci bildirimi için sadece bir parametreye ihtiyacımız vardır : metot adresi. Diğer dillerden farklı olarak C# ta metodun adresi aynı zamanda bu metodun hangi nesne üzerinden de çağrılacağını tutabilir, diğer dillerde ise temsilcilern temsil etttiği metodu çağırabilmek için ayrıca nesnelere ihtiyaç duyulur. Örneğin System.Threading.ThreadStart() metodunun kullanımına bakalım.

Foo MyFoo = new Foo();
ThreadStart del = new ThreadStart(MyFoo.Baz);


Bu, static ve instance metotlarının aynı sentaks ile çağrılabileceğini göstermektedir.



S - 15
: Yaptığım windows pencere uygulamasını her çalıştırdığımda neden pop up şeklinde konsol ekranı gösteriliyor.

C - 15 : Proje ayarlarında "Target Type" özelliğinin Console Application yerine Windows Application olduğuna emin olun. Eğer komut satırı derleyicisini kullanıyorsanız /target:exe argümanı yerine /target:winexe argümanını kullanın.



S - 16
: Gereksiz çöp toplayısınıcı(Garbage Collection) zorla çağırmanın bir yolu var mı?

C - 16 : Evet; Bütün referasnları null değer atayın ve System.GC.Collect() statik metodunu çağırın.

Yıkılması(destruct) gereken nesneleriniz var ve GC nin bunu yapmadığını düşünüyorsanız nesneleri null değere atayarak onların sonlandırıcı metotlarının çağrılmasını sağlayın ver ardından System.GC.RunFinalizers() metodunu çağırın



S - 17
: C#, C dilindeki makroları destekliyormu?

C - 17 : Hayır, C# ta makro yoktur.

__LINE__ ve __FILE__ gibi C dilinde önceden tanımlanmış bazı makroların System.Diagnostics isim alanındaki StackTrace ve StackFrame gibi COM+ ile ilgili sınıflardan elde edilebileceğini unutmayın. Fakat bunlar sadece Debug moddaki derleme için çalışacaktır.



S - 18
: C# derleyicisine bazı dll leri referans vermememe rağmen neden kendisi referans verir.

C - 18 : "csc.rsp" dosyasında bulunan bütün assembly lere C# derleyicisi otomatik olarak referans verir. Bu dosyanın içerdiği assembly leri /r argümanı ile belirtmek zorunda değilsiniz. csc.rsp dosyasının kullanımını komut satırından /noconfig argümanını belirterek engelleyebilirsiniz.

Not : Visual Studio IDE si hiç bir zaman csc.rsp dosyasını kullanmaz.



S - 19
: Delegate/MulticastDelegate (Temsilciler) nasıl bildirilir?

C - 19 : Aşağıda DllImport niteliğinin kullanımına bir örnek verilmiştir.

using System.Runtime.InteropServices;
 
class C
{
    [DllImport("user32.dll")]
    public static extern int MessageBoxA(int h, string m, string c, int type);
 
    public static int Main() 
    {
            return MessageBoxA(0, "Hello World!", "Caption", 0);
    }
}


Yukarıdaki örnek kod yönetilmeyen(unmanaged) DLL deki doğal(native) bir fonksiyonu C# ta bildirmek için minumum gereksinimleri gösterir.C.MessageBoxA() metodu static ve extern sözcükleri ile bildirilmiş, DllImport niteliği ile bu metodun user32.dll dosyasında MessageBoxA ismiyle uygulanmış olduğu belirtilmektedir.



S - 20
: COM+ runtime'ında tanımlanan bir arayüzü uygulamaya çalışıyorum ancak "public * Object GetObject{...}" çalışmıyor gibi. Ne yapmalıyım?

C - 20 : Managed C++'ta "Object * GetObject()"(object türünden gösterici) sentaksı geçerlidir. C# ta ise "public Object GetObject()" biçiminde kullanmak yeterlidir.



S - 21
: C# şablon(template) yapılarını destekliyormu?

C - 21 : Hayır, fakat bir tür şablon olan generics yapılarının C# diline eklenilmesi planlanmaktadır. Bu türler sentaks olarak şablonlara benzerler fakat derleme zamanı yerine çalışma zamanında oluşturulurlar. Bu türlerle ilgili detaylı bilgi için tıklayın.



S - 22
: Item özelliğini kullandığımda neden CS0117 hatası almaktayım?

C - 22 : C# özellikleri destekler ancak Item özelliğinin sınıflar için özel anlamı vardır. Item özelliği aslında varsayılan indeskleyici olarak yer alır. Bu imkanı C# ta elde etmek için Item sözcüğünü atmak yeterlidir. Aşağıda örnek program gösterilmiştir.

using System;
using System.Collections;
 
class Test
{
    public static void Main() 
    {
        ArrayList al = new ArrayList();
        al.Add( new Test() );
        al.Add( new Test() );
        Console.WriteLine("First Element is {0}", al[0]);
    }
}


WriteLine metodunda .Items[0] 'ın kullanılmadığına dikkat edin.



S - 23
: Herhangi bir fonksiyonumu "out int" parametresi alacak şekilde tasarlmaya çalışıyorum. Bu metoda göndereceğim int değişkenini nasıl bildirmeliyim?

C - 23 : Değişken bildirimi int türünden yapmalısınız fakat bu değişkeni fonksiyona parametre olarak gönderirken aşağıdaki gibi "out" anahtar sözcüğünü de kullanmalısınız.

   int i;
   foo(out i);

foo metodu aşağıdaki gibi bildirilmiştir.

   [return-type] foo(out int o) { }



S - 24
: C++'taki referanslara benzer bir yapı C#' ta varmıdır? (Ör : void foo(int &x) gibi )

C - 24 : C#'ta bunun karşılığı ref parametreleridir.

class Test
{
    public void foo(ref int i) 
    {
        i = 1;
    }
 
    public void bar() 
    {
        int a = 0;
        foo(ref a);
        if (a == 1)
            Console.WriteLine("It worked");
    }
 
    public static void Main() {}
}


Not: Metot çağrımında da ref sözcüğünün kullanıldığına dikkat edin!



S - 25
: C#'ta inout argümanları nasıl bildirilir?

C - 25 : inout'un C# taki karşlığı ref'tir. Örneğin :

public void MyMethod (ref String str1, out String str2) 
{
    ...
}


Bu metot aşağıdaki biçimde çağrılmalıdır.

    String s1;
    String s2;
    s1 = "Hello";
    MyMethod(ref s1, out s2);
    Console.WriteLine(s1);
    Console.WriteLine(s2);


Not : Hem metot çağrımı hemde metot bildirimi sırasında ref sözcüğünün kullanıldığına dikkat edin.



S - 26
: Yıkıcı metotlar(destructors) ve GC C#'ta ne şekilde çalışır?

C - 26 : C# ta sonlandırıcı metotlar vardır ve kullanımı aşağıdaki gibidir. (Bu sonlandırıcı metotlar C++ taki yıkıcı metotlara benzer, tek farkı çağrılacağı garanti altına alınmamıştır.)

class C
{
    ~C()
    {
        // your code
    }
 
    public static void Main() {}
}


Bu metotlar object.Finalize() metodunu aşırı yüklerler ve GC nesneyi yok ederken bu metodu kullanır.



S - 27
: Derleme sırasında neden "CS5001: does not have an entry point defined - tanımlanmış giriş noktası yok- " hatasını alıyorum?

C - 27 : Bu hata en çok Main metodunu main şeklinde yazdığınızda karşınıza çıkar. Giriş noktası olan bu Main metodunun bildirimi aşağıdaki gibi olmalıdır :

class test 
{
    static void Main(string[] args) {}
}



S - 28
: Visual J++ ta "synchronized" olarak bildrilen metotları C# diline nasıl taşırım?

C - 28 :
Orjinal Visual J++ kodu:

public synchronized void Run() 
{
    // function body
}


C# diline taşınmış hali

class C
{
    public void Run()
    {
        lock(this)
        {
            // function body 
        }
    }
 
    public static void Main() {}
} 




S - 29
: Kanal(thread) senkronizasyonu(Object.Wait, Notift ve CriticalSection) C#'ta nasıl sağlanır?

C - 29 :
lock ile işaretlemiş bloklar bu işe yarar :

lock(obj) 
{
    // code
}


kod parçasının karşılığı

try 
{
    CriticalSection.Enter(obj);
    // code
} 
finally 
{
    CriticalSection.Exit(obj);
}




S - 30
: Statik yapıcı metotların sentaksı nasıldır?

C - 30 :
Aşağıda MyClass adlı sınıfın statik yapılandırıcısının bildirimi gösterilmiştir.

class MyClass
{
    static MyClass()
    {
        // initialize static variables here
    }
 
    public static void Main() {}
}





S - 31
: Bir özelliğin get ve set bloklarını farklı erişim belirleyicileri ile bildirmek mümkünmüdür?

C - 31 : Hayır, bir özelliğin belirtilen erişim belirleyicisi aynı zamanda hem get hem de set bloklarınınn erişim belirleyicisidir. Fakat yapmak istediğinizi muhtemelen sadece get bloğu olan yani readonly olarak bildirip set bloğunu private yada internal olan bir metot yapacak şekilde gerçekleştirebilirsiniz.



S - 32
: Tek bir assembly de çoklu dil desteğini nasıl sağlayabilirim?

C - 32 : Bu şu an için Visual Studio.NET tarafından desteklenen bir özellik değildir.




S - 33
: C# dizi türünden olan özellikleri destekliyor mu?

C - 33 : Evet, aşağıda buna bir örnek verilmiştir:

using System;
 
class Class1 
{
    private string[] MyField;
 
    public string[] MyProperty 
    {
        get { return MyField;  }
        set { MyField = value; }
    }
}
 
class MainClass
{
    public static int Main(string[] args) 
    {
        Class1 c = new Class1();
 
        string[] arr = new string[] {"apple", "banana"};
        c.MyProperty = arr;
        Console.WriteLine(c.MyProperty[0]);  // "apple"
    
        return 0;
    }
}





S - 34
: Birden fazla assembly ile çoklu dil desteği sağlanabilirmi?

C - 34 : Malesef şu an için IDE de bu desteklenmiyor. Bunu yapabilmek için komut satırından projenizi /target:module argümanı ile derleyip modüllere ayırmanız gerekir. Ve oluşturduğunuz bu modülleri birleştirmek için yine komut satırından al(alink) aracını çalıştırarak bu modüllerin birleştirilmesini sağlayın.




S - 35 : COM nesnelerine erişmek için opsiyonel olan parametreleri nasıl simule edebilirim?

C - 35 : Opsiyonel parametreler için System.Reflection altında bulunan Missing sınıfı kullanılır. Her bir parametre için Missing.Value değeri kullanılabilir.



S - 36 : C++'taki varsayılan metot argümanlarının bir karşılığı C#'ta var mı?

C - 36 : Varsayılan argüman desteği yoktur ancak aynı etkiyi metot yükleme ile rahatlıkla yapabilirsiniz.

Bu problem için metot yüklemeyi tercih etmemizin sebebi ileriki zamanlarda kaynak kodu yeniden derlemeden varsayılan argümanı değiştirme imkanı vermesidir. C++ taki varsayılan argümanlar derşenmiş kodun içine gömüldüğü için sonradan bu argümanı kaynak kodu derlemeden değiştirmek mümkün değildir.



S - 36 : İçiçe geçmiş bloklarda yada döngülerde hangi bloğun sonlandırdıldığını belirtmek için kolay bir yol varmıdır?

C - 36 : Bu işin en kolay yolu goto atlama deyimini aşağıdaki gibi kullanmaktır.

using System;
class BreakExample 
{
    public static void Main(String[] args) 
    {
        for(int i=0; i<3; i++) 
        {
            Console.WriteLine("Pass {0}: ", i);
            for( int j=0 ; j<100 ; j++ ) 
            {
                if ( j == 10) goto done;
                Console.WriteLine("{0} ", j);
            }
            Console.WriteLine("This will not print");
        }
        done: