Czy istnieje jakakolwiek kara, która powinna być ustawiona tylko jako zerowa, kiedy naprawdę jej potrzebujesz?Dlaczego nie wszystkie typy wartości są zerowe?
Dzięki
Czy istnieje jakakolwiek kara, która powinna być ustawiona tylko jako zerowa, kiedy naprawdę jej potrzebujesz?Dlaczego nie wszystkie typy wartości są zerowe?
Dzięki
Różne powody:
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>
int
, nie chcieć że jest pustych ... chcę być int
, a ja nie chcę mieć do odprawy na uchwyt/nullbyte[]
, 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ć:
==
na GetValueOrDefault()
każdegopartii z głową ....
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.
Musisz zawinąć je w Nullable
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
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
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.
Kara jest znacznie gorsza niż dodatkowe słowo. Konstrukcja struktury zerowalnej oznacza, że utworzenie 'Nullable
Oprócz Marc Gravell odpowiedzi, sprawdź kod odbitego od Nullable <T>:
public struct Nullable<T> 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ą.
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.
Nie zapomnij o dodatkowym? operator również wrzucił. int i = j ?? k; // jeśli j ma wartość null, użyj k. –
cóż, to nie jest specyficzne dla 'Nullable' - ale inny dobry punkt –
@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? ;-) –