none
string.Empty ve "" arasındaki fark RRS feed

  • Genel Tartışma

  • Paylaşılan kodlarda bolca "" (empty string) görüyorum. string.Empty kullanmak yerine "" yazmanın arasındaki fark nedir? düşüncelerinizi yazarmısınız?

    www.mvcblog.org
    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    3 Kasım 2015 Salı 06:52
    Moderatör

Tüm Yanıtlar

  • Deleted
    3 Kasım 2015 Salı 07:09
  • Aynışey değil işte, çok görüyorum bunu.

    "" yazmak, ram üzerinde içinde elemanı olmayan yeni bir char dizisi oluşturur. yani 

    var a = "";
    var b = "";
    var c = "";
    var d = "";
    


    bu kullanım ram'de 4 farklı char[] instance'ı oluşturur.

    var a = string.Empty;
    var b = string.Empty;
    var c = string.Empty;
    var d = string.Empty;
    

    ama bu , string classı içindeki static field sadece bir adet olacağı için sadece 1 defa yer kaplar.


    www.mvcblog.org
    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    3 Kasım 2015 Salı 07:15
    Moderatör
  • Hocam vermiş olduğunuz bilgiden dolayı teşekkürler. Doğru bildiğimiz yanlışlar.

    Önay Hocam string lerde null kullanıyoruz aynı kategoriye girer mi?

    string a=null;
    
    string b=null;
    


    kdrgny@outlook.com

    3 Kasım 2015 Salı 07:36
  • Deleted
    3 Kasım 2015 Salı 08:09
  • Aynışey değil işte, çok görüyorum bunu.

    "" yazmak, ram üzerinde içinde elemanı olmayan yeni bir char dizisi oluşturur. yani 

    var a = "";
    var b = "";
    var c = "";
    var d = "";


    bu kullanım ram'de 4 farklı char[] instance'ı oluşturur.

    var a = string.Empty;
    var b = string.Empty;
    var c = string.Empty;
    var d = string.Empty;

    ama bu , string classı içindeki static field sadece bir adet olacağı için sadece 1 defa yer kaplar.


    www.mvcblog.org
    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com


    Ben String.Empty olarak kullanıyorum. Peki programda 1000 yerde bu şekilde tanımlansa, aktif pencere vs. 500 yerde o an kullanılıyor olsa hafızaya etkisi nedir? Bellekte etkisi nedir yani ne kadar Ram harcar mesela? Programın çökmesine sebep olması zor gibi geliyor. Garbage Collector bunlarda işe yaramıyor mu?
    3 Kasım 2015 Salı 08:53
  • Hocam vermiş olduğunuz bilgiden dolayı teşekkürler. Doğru bildiğimiz yanlışlar.

    Önay Hocam string lerde null kullanıyoruz aynı kategoriye girer mi?

    string a=null;
    
    string b=null;


    kdrgny@outlook.com

    hayır aynı kategoriye girmez. null başka şey , emptystring başka şey;

    null : ram'de yeri açılmamış anlamına geliyor. (Bunun için kullanamıyoruz zaten. Bu forumda "Null Reference Exception" isimli binlerce soru vardır :))

    empty string : ram'de yeri açılmış ama içinde hiç char yok demektir.

    zaten bu karışıklığı önlemek için string içinde IsNullOrEmpty isimli bir static method var ;)


    www.mvcblog.org
    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    3 Kasım 2015 Salı 09:04
    Moderatör


  • Ben String.Empty olarak kullanıyorum. Peki programda 1000 yerde bu şekilde tanımlansa, aktif pencere vs. 500 yerde o an kullanılıyor olsa hafızaya etkisi nedir? Bellekte etkisi nedir yani ne kadar Ram harcar mesela? Programın çökmesine sebep olması zor gibi geliyor. Garbage Collector bunlarda işe yaramıyor mu?

    Etkisini ölçmedim, performans'ı farkedilirmi-farkedilmezmi, ya da kaç adet instance'da farkedilir bilmiyorum. Ama GC açısından; string bir class olsada stackta saklanan value tipli bir type dir, yani referans tipler gibi heapta saklanamaz, bu açıdan GC referanslarını sayamaz diye düşünüyorum.

    Evet programın crash olmasına neden olmaz, OutOfMemory exception oluşmasına neden olacak kadar kullanımı olma ihtimali çok az.
    Ama gerçekte olan boşu boşuna ram de açılan yerlerdir. 


    www.mvcblog.org
    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    3 Kasım 2015 Salı 09:09
    Moderatör
  • Önay,

    Bu yine de en basitlerinden. Ben de cok sayida soyle seyler goruyorum:

    string x = "...";
    x += "....";
    

    Hatta bunu bir dongu icerisinde yapanlar da var. 


    3 Kasım 2015 Salı 10:02
    Yanıtlayıcı
  • Hocam, bilmiyorum bende mi bi problem var; bi şey yazıyorsam ne-nedir bilmezsem rahat edemiyorum. Verdiğin örnekteki += operatörünün overload olduğunu bilerek kullanıldığından emin değilim, hatta operatör yapısının bilinip kullanıldığından da emin değilim. 

    Yine söyleyim belki bu benim aşırı titizlik problemimmidir bilemiyorum.


    www.mvcblog.org
    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    3 Kasım 2015 Salı 10:25
    Moderatör
  • Haklisin, operator overloading ile ilgili kod gorulmuyor zaten. Benim orada gostermeye calistigim +' dan ziyade, stringlerin tamamen farkli oldugu idi. Cogu kimse eskisinin uzerine eklendigini saniyor.
    3 Kasım 2015 Salı 10:32
    Yanıtlayıcı
  • Aslında senin cevapta çok doğru değil.

    ....

    Tüm mesele string interning den meydana geliyor. Aşağıdaki koda bakalım :

    var a = "test";
    var b = Console.ReadLine();
    Console.WriteLine( Object.ReferenceEquals(a,b));

    bu kod ne yazarsak yazalım geriye False döenecektir. Bu iki string değerleri eşit olsada her iki string için farklı bellek bölgeleri işgal edilmiştir.

    Bir de şu koda bakalım :

    var a = "test";
    
    var b = string.Intern(Console.ReadLine());
    Console.WriteLine( Object.ReferenceEquals(a,b));

    bu kodda ise komut satırından "test" girdiğimizde  aynı referans noktasının işaret edildiğini görüyoruz.

    Burada "test" şeklinde kodun içine yazdığımız string jit complier tarafından "otomatik" olarak intern edilmişti biz de readline ile okuduğumuz string daha öneden intern edildiyse o referansı kullan dedik.

    Yani:

    var a = "test";
    var b = "test";
    Console.WriteLine( Object.ReferenceEquals(a,b));

    bu üsteki kodda a ve b aynı referansını noktasını bu intern mekanizmasının otomatik olarak çalışmasından dolayı alır. Yani a,b,c,d örneğin her zaman doğru olmaz...

    .net 'in ilk versiyonlarında bu otomatik işlem yoktu yani bir önceki örnekde alacağımız cevap False idi. Bu yüzden String.Empty denilen arkadaşın referansı kopyalanarak her boş string için farklı bellek bölgesi işgal edilmesi String.Intern.... şeklinde sürekli çağırılmadan engelleniyordu.

    ...

    Günümüzde string.Empty nin performans katkısı yok. Ama kullanıcıdan alacağınız değişkenler ile oluşturacağınız generation tollarında stringbuilder ile string.Intern birliktelği ile bellekten ciddi tasaruf etmeniz olası.


    Ben okunurluğuda arttırdığı için her zaman string.Empty kullanyorum.




    3 Kasım 2015 Salı 11:07
  • Stringler heap de saklanır ve unmutable referans tipindedirler. Ve verileri heap de saklanması gerekir, aksi bir bilgiyi ilk defa duyuyorum. Yanlışım varsa kanıt istiyorum :)

    https://msdn.microsoft.com/en-us/library/4d43ts61(v=vs.90).aspx

    C# lanugage specs. sayfa 4 :


    Category

    Description

    Value types

    Simple types

    Signed integral: sbyte, short, int, long

    Unsigned integral: byte, ushort, uint, ulong

    Unicode characters: char

    IEEE floating point: float, double

    High-precision decimal: decimal

    Boolean: bool

    Enum types

    User-defined types of the form enum E {...}

    Struct types

    User-defined types of the form struct S {...}

    Nullable types

    Extensions of all other value types with a null value

    Reference types

    Class types

    Ultimate base class of all other types: object

    Unicode strings: string

    User-defined types of the form class C {...}

    Interface types

    User-defined types of the form interface I {...}

    Array types

    Single- and multi-dimensional, for example, int[] and int[,]

    Delegate types

    User-defined types of the form e.g. delegate int D(...)


    3 Kasım 2015 Salı 11:33
  • stack dil surcmesi olmus, ben de yeni farkettim. Ben de o nedenle yazmistim aslinda benim ornegi, immutable diye :)

    Neyse bunlar fazla akademik detaylar burasi icin.

    3 Kasım 2015 Salı 11:37
    Yanıtlayıcı
  • String için heap geçerli olabilir ama string için durum farklı;

    string bir char* değilmidir? char da primitif bir type ve struct olduğuna göre veriler stacktadır, ama dizinin referansı heapta dır diye biliyorum ve yanılmıyorsam sadece string'e özel bir durum bu.

    https://msdn.microsoft.com/en-us/library/aa711900(v=vs.71).aspx 

    Burada string için Primitif tip yazıyor.

    Eğer bir instance'ı new keywordu ile oluşturuyorsak bu bir referans tiptir. value tipleri new keywordu ile oluşturmayız

    int i = 5; //<- stack

    int[] d = new int[10]; //<- heap

    gibi


    www.mvcblog.org
    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com


    3 Kasım 2015 Salı 12:00
    Moderatör
  • String için heap geçerli olabilir ama string için durum farklı;

    String ve string int ve Int32 de olduğu gibi tamamen aynı şeydir, tamamen aynı IL kodu üretilir. Birisi CTS .net tipiyken diğeri C# tipidir. string String için bir aliasdır sadece. 

    https://msdn.microsoft.com/en-us/library/ya5y69ds.aspx


    string bir char* değilmidir?

    string bir char[] dır diye kabul edersek, bir önceki örneğimde belirttiğim gibi tüm arrayler zaten referans tipidir.

    char da primitif bir type ve struct olduğuna göre veriler stacktadır, ama dizinin referansı heapta dır diye biliyorum ve yanılmıyorsam sadece string'e özel bir durum bu.

    https://msdn.microsoft.com/en-us/library/aa711900(v=vs.71).aspx 

    Burada string için Primitif tip yazıyor.

    Öncelikle bu kaynak VB üzerine ve vb de primitve tanımı System namespace'i içerisinde olmasıyla tanımlanıyor. Fakat .net olarak ele aldığımızda durum CLR da bulunup bulunmamasına göre değişiyor. Örnekte bir çok type string, decimal gibi zaten primitve type değiller. Bunu öğrenmek için typeof(int).IsPrimitive şeklinde kod yazabilirsin.

    Eğer bir instance'ı new keywordu ile oluşturuyorsak bu bir referans tiptir. value tipleri new keywordu ile oluşturmayız

    int i = 5; //<- stack

    int[] d = new int[10]; //<- heap

    gibi



    tüm tipler için new keywordü kullanılabilir var a = new int(); a= 4; gibi kullanım geçerli bir c# kodudur. String'inde new ile farklı farklı oluşturulması mümkündür. Normal bir referans tipi gibi oluşturulmaması sadece değer tipi gibi davranması içindir.

    Tüm değer tipleri ValueType den türerken string doğrudan object'den türer. Bir değer tipi null referans almazsken string alabilir.

    3 Kasım 2015 Salı 12:30
  • primitif tipin heap ta olduğunu tartışmak anlamsız geliyor bana.

    www.mvcblog.org
    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    3 Kasım 2015 Salı 12:51
    Moderatör
  • primitif tipin heap ta olduğunu tartışmak anlamsız geliyor bana.

    String zaten primitive değil! String bir referans tipi. Aynı zamanda bir Char dizisi gibi düşünebilirsin. Tüm dizilerde referans tipidir. Dizilerin elemanları değer tipinden olsalar da boxlanmış şekilde heap de saklanırlar. 

    https://msdn.microsoft.com/en-us/library/ms379570(v=vs.80).aspx



    3 Kasım 2015 Salı 13:21