2009-07-04 11 views

Odpowiedz

20

Różne powody:

  • Historia: Nullable<T> nie istniał aż .NET 2.0, i nie może przełamać istniejący kod - szczególnie z różnymi zasadami Karkas Nullable<T>
  • znaczenie: jeśli chcę int, nie chcieć że jest pustych ... chcę być int, a ja nie chcę mieć do odprawy na uchwyt/null
  • Spacja: dodaje dodatkowy koszt dla każdego struct ... w szczególności, imag i byte[], a teraz rozważ, czy byte był zerowalny - wiele dodatkowych kosztów; * Plus byłoby zatrzymać robisz Blits etc *
  • Wydajność: Nullable<T> dodaje wiele dodatkowych kar; w szczególności wiele ukrytych połączeń z .HasValue i .Value/.GetValueOrDefault(); to jest pokazane w szczególności w „podnoszony operatorów” - czyli x + y staje coś jak poniżej, które dodaje się do ciasnych pętli itp:

    (x.HasValue && y.HasValue) ? (x.GetValueOrDefault() + y.GetValueOrDefault()) : null

Podobnie x == y musi sprawdzić:

  • jeżeli obie wartości null => true
  • jeśli jedna wartość null => false
  • w inny sposób wykorzystywać == na GetValueOrDefault() każdego

partii z głową ....

+0

Nie zapomnij o dodatkowym? operator również wrzucił. int i = j ?? k; // jeśli j ma wartość null, użyj k. –

+0

cóż, to nie jest specyficzne dla 'Nullable ' - ale inny dobry punkt –

+0

@Chris to działa w ogóle? j nie może być wartością null, inaczej nie można jej przypisać do typu wartości, prawda? ;-) –

1

Jakie typy wartości są faktycznie zerowalne? Nie znam żadnego.

EDYCJA: Jeśli odwołujesz się do typu ciągu, to nie jest to typ wartości, ale typ odniesienia.

+0

Musisz zawinąć je w Nullable typ – philsquared

+1

Ale to jest coś innego niż wtedy. Wierzę, że rozrusznik tematu oznaczał typy wartości zerowe po wyjęciu z pudełka, prawdopodobnie odwołując się do typu łańcucha. – User

+1

Myślę, że OP oznacza coś w stylu "jeśli typy wartości mogą zostać unieważnione, dlaczego nie wszystkie są od początku zerowe?". – Guffa

6

Tak, jest kara. Struktura Nullable<T> zawiera wartość, a także znacznik logiczny, który określa wartość zerową wartości.

Mimo że wartość logiczna to tylko jeden bajt, struktury są wyrównane do granic wyrazów. Numer int wykorzystuje cztery bajty pamięci, ale kod int? wymaga ośmiu bajtów.

+0

Kara jest znacznie gorsza niż dodatkowe słowo. Konstrukcja struktury zerowalnej oznacza, że ​​utworzenie 'Nullable ' będzie wymagało co najmniej jednej dodatkowej operacji "kopiowania T", a każdy kod, który otrzyma 'Nullable 'będzie musiał wykonać co najmniej jedną dodatkową operację" kopiowania T "w aby z niego skorzystać. – supercat

0

Oprócz Marc Gravell odpowiedzi, sprawdź kod odbitego od Nullable <T>:

public struct Nullable&lt;T&gt; where T: struct 
{ 
    private bool hasValue; 

    internal T value; 

    public Nullable(T value) 
    { 
     this.value = value; 
     this.hasValue = true; 
    } 

    public bool HasValue 
    { 
     get 
     { 
      return this.hasValue; 
     } 
    } 
    public T Value 
    { 
     get 
     { 
      if (!this.HasValue) 
      { 
       ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue); 
      } 
      return this.value; 
     } 
    } 
    public T GetValueOrDefault() 
    { 
     return this.value; 
    } 

    public T GetValueOrDefault(T defaultValue) 
    { 
     if (!this.HasValue) 
     { 
      return defaultValue; 
     } 
     return this.value; 
    } 

    public override bool Equals(object other) 
    { 
     if (!this.HasValue) 
     { 
      return (other == null); 
     } 
     if (other == null) 
     { 
      return false; 
     } 
     return this.value.Equals(other); 
    } 

    public override int GetHashCode() 
    { 
     if (!this.HasValue) 
     { 
      return 0; 
     } 
     return this.value.GetHashCode(); 
    } 

    public override string ToString() 
    { 
     if (!this.HasValue) 
     { 
      return ""; 
     } 
     return this.value.ToString(); 
    } 

    public static implicit operator T?(T value) 
    { 
     return new T?(value); 
    } 

    public static explicit operator T(T? value) 
    { 
     return value.Value; 
    } 
} 

You” Zauważ, że istnieje boolean HasValue i jak właściwości go używają.

0

Rozważ wdrożenie.Liczbą całkowitą C# jest zdefiniowana jako

public struct Int32 : IComparable, IFormattable, IConvertible, IComparable<int>, IEquatable<int> 

struct są przechowywane bezpośrednio na stosie, a nie obiektów odniesienia, które są wskaźnikami do pamięci (odniesienia znajdującego się w stos, ale przydział w stosie) .

Odwołanie NULL oznacza po prostu, że wskaźnik w stosie nie został zainicjalizowany do położenia w stercie.