Default (nesne) ne yapar; C # dilinde yapmak?


133

Google'da arama yalnızca anahtar kelimeyi buluyor, ancak şunu söyleyen bir kodla karşılaştım:

MyVariable = default(MyObject);

ve bunun ne anlama geldiğini merak ediyorum.

Yanıtlar:


189
  • Bir başvuru türü için döndürür null
  • Nullable<T>Bunun dışındaki bir değer türü için sıfır başlatılmış bir değer döndürür
  • İçin Nullable<T>boş (sözde null) değer döndürür (aslında bu ilk merminin bir yeniden ifadesidir, ancak açık yapma değer)

En büyük kullanımı default(T)jeneriklerde ve Try...model gibi şeylerdir :

bool TryGetValue(out T value) {
    if(NoDataIsAvailable) {
        value = default(T); // because I have to set it to *something*
        return false;
    }
    value = GetData();
    return true;
}

Olduğu gibi, onu alanları / değişkenleri başlatmanın zor olduğu bazı kod üretmede de kullanıyorum - ancak türünü biliyorsanız:

bool someField = default(bool);
int someOtherField = default(int)
global::My.Namespace.SomeType another = default(global::My.Namespace.SomeType);

1
Ben oluşturursanız class Fooözelliğiyle int n. Bunun yerine söylemesi defaultiçin "aşırı yükleme" yapabilir miyim ? n50
Pratik Deoghare

4
@ The Machine Charmer: Hayır default. Aşırı yüklenemezsiniz .
Jeff Yates

Değil midir int foo = default(int);aynıydı int foo;? Yani, başlatılmamış ints varsayılan olarak aynı değere sahip değil default(int)mi?
Adam Parkin

1
@AdamParkin alanlardan mı yerellerden mi bahsettiğinize bağlıdır; evet, alanlar sıfır-d boşluğuna başlar, aynı şekilde default(...); halk yok (teknik olarak her ne kadar varsayılan değerleri .locals inittekrar sıfıra getirememe IL araçlarında, ama bunu gözlemlemek için güvensiz mekanizmalarını kullanmak gerekir)
Marc Gravell

"Bu, boş (psuedo-null) değerini döndürür ... bu ne? Cümle bitmemiş gibi görünüyor.

14

defaultanahtar kelime, nullreferans türleri ve zerosayısal değer türleri için dönecektir .

İçin structs, bu yapı, her üye, bir değer ya da referans türleri olup olmadığına bağlı olarak sıfır ya da boş başlatılır dönecektir.

MSDN'den

Simple Sample code :<br>
    class Foo
    {
        public string Bar { get; set; }
    }

    struct Bar
    {
        public int FooBar { get; set; }
        public Foo BarFoo { get; set; }
    }

    public class AddPrinterConnection
    {
        public static void Main()
        {

            int n = default(int);
            Foo f = default(Foo);
            Bar b = default(Bar);

            Console.WriteLine(n);

            if (f == null) Console.WriteLine("f is null");

            Console.WriteLine("b.FooBar = {0}",b.FooBar);

            if (b.BarFoo == null) Console.WriteLine("b.BarFoo is null");

        }
    }

ÇIKTI:

0
f is null
b.FooBar = 0
b.BarFoo is null

3

Varsayılan değeri MyObject. Genel Koddaki varsayılan Anahtar Kelimeye bakın (C # Programlama Kılavuzu) (MSDN):

Genel sınıflarda ve yöntemlerde ortaya çıkan sorunlardan biri, aşağıdakileri önceden bilmediğinizde parametreleştirilmiş bir T türüne varsayılan bir değerin nasıl atanacağıdır:

  • T'nin referans türü mü yoksa değer türü mü olacağı.
  • T bir değer türü ise, sayısal bir değer mi yoksa yapı mı olacağı.

Parametreli bir T türünün bir t değişkeni verildiğinde, t = null ifadesi yalnızca T bir başvuru türü ise ve t = 0 yalnızca sayısal değer türleri için çalışır, yapılar için çalışmazsa geçerlidir. Çözüm, referans türleri için null ve sayısal değer türleri için sıfır döndüren default anahtar sözcüğünü kullanmaktır. Yapılar için, değer veya başvuru türü olup olmadıklarına bağlı olarak, yapının her bir üyesini sıfır veya boş olarak döndürür. GenericList sınıfından alınan aşağıdaki örnek, varsayılan anahtar kelimenin nasıl kullanılacağını gösterir. Daha fazla bilgi için bkz. Jeneriklere Genel Bakış.

public class GenericList<T>
{
    private class Node
    {
        //...

        public Node Next;
        public T Data;
    }

    private Node head;

    //...

    public T GetNext()
    {
        T temp = default(T);

        Node current = head;
        if (current != null)
        {
            temp = current.Data;
            current = current.Next;
        }
        return temp;
    }
}

2

Tür parametresinin varsayılan değerini belirtir.Bu, başvuru türleri için boş ve değer türleri için sıfır olacaktır.

Varsayılana bakın


1

defaultAnahtar kelime döner istenen türde bir değişken için "varsayılan" ya da "boş" bir değer.

(Tanımlanır bütün referans tipleri için class, delegatevs.), bu null. (Tanımlanmış değer türleri için struct, enumvb) bu (örneğin, her sıfır değer int 0, DateTime 0001-01-01 00:00:00vs.).

Çoğunlukla hem referans hem de değer türlerine uygulanabilen genel kodla kullanılır, çünkü nullbir değer türü değişkenine atayamazsınız .


0

Bir nesnenin varsayılan değerini bir değişkene ayarlayacaktır: referans türleri için null ve değer türleri için 0.


0

Belki bu size yardımcı olabilir:

using System;
using System.Collections.Generic;
namespace Wrox.ProCSharp.Generics
{
    public class DocumentManager < T >
    {
        private readonly Queue < T > documentQueue = new Queue < T > ();
        public void AddDocument(T doc)
        {
            lock (this)
            {
                documentQueue.Enqueue(doc);
            }
        }

        public bool IsDocumentAvailable
        {
            get { return documentQueue.Count > 0; }
        }
    }
}

Genel türlere null atamak mümkün değildir. Bunun nedeni, genel bir türün bir değer türü olarak somutlaştırılabilmesi ve null değerine yalnızca başvuru türlerinde izin verilmesidir. Bu sorunu aşmak için varsayılan anahtar kelimeyi kullanabilirsiniz. Varsayılan anahtar sözcükle, referans türlerine null ve değer türlerine 0 atanır.

public T GetDocument()
{
    T doc = default(T);
    lock (this)
    {
        doc = documentQueue.Dequeue();
    }
    return doc;
}

Varsayılan anahtar kelimenin kullanıldığı bağlama bağlı olarak birden çok anlamı vardır. Switch deyimi, varsayılan durumu tanımlamak için bir varsayılan kullanır ve jeneriklerle varsayılan, bir başvuru veya değer türü olmasına bağlı olarak genel türleri null veya 0 olarak başlatmak için kullanılır.


0

Genel bir tür parametresini başvuru türü olarak sınırlamak için kısıtlamalar uygulanmadığında, yapı gibi bir değer türü de geçilebilir. Bu tür durumlarda, tür parametresini null ile karşılaştırmak her zaman yanlış olur , çünkü bir yapı boş olabilir, ancak hiçbir zaman boş olamaz

Yanlış kod

public void TestChanges<T>(T inputValue)

            try
            {
                if (inputValue==null)
                    return;
                //operation on inputValue

           }
            catch
            {
                // ignore this.
            }
        }

düzeltilmiş

public void TestChanges<T>(T inputValue)

            try
            {
                if (object.Equals(inputValue, default(T)) )
                    return;
                //operation on inputValue

           }
            catch
            {
                // ignore this.
            }
        }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.