11

本当に必要な場合にのみnull許容として設定する必要があるなどのペナルティはありますか?

ありがとう

4

5 に答える 5

20

様々な理由:

  • 履歴:Nullable<T>.NET 2.0まで存在せず、既存のコードを壊すことはできません-特にNullable<T>
  • 意味:もし私が望むなら、それをnull許容にしたくintないかもしれません...私はそれをにしたいと思います、そして私はnullをチェック/処理する必要はありませんint
  • スペース:各構造体に余分なコストが追加されます...特に、を想像して、 null許容byte[]かどうかを検討してください-多くの余分なオーバーヘッド。*それに加えて、それはあなたがブリットなどbyteをするのを止めるでしょう*
  • パフォーマンス:Nullable<T>多くの追加のペナルティが追加されます。特に、.HasValueおよび.Value/への隠された呼び出しがたくさんあり.GetValueOrDefault()ます。これは、特に「持ち上げられた演算子」で示されます。つまりx + y、以下のようになり、タイトなループなどが追加されます。

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

同様に、x == y以下を確認する必要があります。

  • 両方がnull=>trueの場合
  • 1つのnull=>falseの場合
  • それ以外の場合は、それぞれに使用==しますGetValueOrDefault()

たくさんのオーバーヘッド...

于 2009-07-04T15:33:53.240 に答える
6

はい、ペナルティがあります。構造には、値と、値のNullable<T>nullを決定するブールフラグが含まれています。

ブール値は1バイトだけですが、構造体は単語の境界に均等に配置されます。は4バイトのintメモリを使用しますが、int?8バイトが必要です。

于 2009-07-04T15:21:52.640 に答える
1

どの値型が実際にnull許容ですか?私は誰も知りません。

編集:文字列型を参照する場合、それは値型ではなく、参照型です。

于 2009-07-04T15:20:36.230 に答える
0

Marc Gravellの回答に加えて、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;
    }
}

HasValueブール値の存在と、プロパティがそれをどのように使用しているかに気付くでしょう。

于 2009-07-04T17:01:17.007 に答える
0

実装を検討してください。C#の整数は次のように定義されます

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

メモリへのポインタであるオブジェクト参照とは対照的に、構造体はスタックに直接格納されます(参照自体はスタックにありますが、割り当てはスタックにあります)。

NULL参照は、スタック内のポインターがヒープ内の場所に初期化されていないことを意味します。

于 2009-07-29T20:18:09.713 に答える