3

これは実際には最適化の質問でも何でもありません。それは本質的に、一体何が起こっているのかという種類の質問です。シングルトン パターンは、オブジェクトの単一インスタンスを複数回使用するために使用されます。これで十分ですが、構造体で同様のパターンを実行しようとすると、単一のインスタンスが得られません。

Colorの構造体で何かをしようとして、これについて来ましたSystem.Drawing。コード例を次に示します。

    class Colors
    {
        private static Color _red;
        public static Color Red
        {
            get
            {
                if (_red.IsEmpty)
                    _red = Color.FromArgb(0xFF, 0xFF, 0x42, 0x39);

                return _red;
            }
        }
    }

    static void Main(string[] args)
    {
        var redOne = Colors.Red;
        var redTwo = Colors.Red;

        Console.WriteLine("redOne.Equals(redTwo) : {0}", redOne.Equals(redTwo));
        Console.WriteLine("redOne == redTwo : {0}", redOne == redTwo);
        Console.WriteLine("Object.Equals(redOne, redTwo) : {0}", Object.Equals(redOne, redTwo));
        Console.WriteLine("Object.ReferenceEquals(redOne, redTwo) : {0}", Object.ReferenceEquals(redOne, redTwo));
        Console.ReadLine();
    }

この出力は次のとおりです。

redOne.Equals(redTwo) : True
redone == redTwo : True
Object.Equals(redOne, redTwo) : True
Object.ReferenceEquals(redOne, redTwo) : False

最初の 3 つの結果は当然のことですが、最後の結果には驚かされました。さて、私の最善の推測は、通常の値型がそうであるように、_redが返されたときColors.Redにコピーを返しているということです。したがって、 のインスタンスは 1 つしかありませんが、新しいインスタンス_redColors.Red返し、それが redOne と redTwo に格納されます。私の考えは正しいですか?

また、それ正しければ、構造体でstaticキーワードを使用する意味はありますか?

ありがとう

4

3 に答える 3

7

ReferenceEquals は構造体/値型では機能せず、クラスのみで機能します。

2 つの構造体で ReferenceEquals を呼び出すと、各構造体が独自のメモリ位置に「ボックス化」され、2 つの (明らかに) 異なるアドレスが比較されます。

クラスはすでに参照型であるため、ReferenceEquals の呼び出しはインスタンスの実際のアドレスを比較します。

基本的に、'Red' の静的コピーを保存する必要はありません。コードを次のように変更します。

class Colors
{
    public static Color Red
    {
        get
        {
            return Color.FromArgb(0xFF, 0xFF, 0x42, 0x39);
        }
    }
}

追加資料: MSDN - 構造体 (C# プログラミング ガイド)

于 2013-01-03T00:01:54.740 に答える
6

したがって、_red のインスタンスは 1 つしかありませんが、Colors.Red はまったく新しいインスタンスを返し、それが redOne と redTwo に格納されます。私の考えは正しいですか?

はい。Color は値型であるため、2 つのコピーがあります。を使用する場合はReferenceEquals、構造体を にボックス化し、ボックス化された 2 つの (明確に異なる) オブジェクトobjectを呼び出します。Object.ReferenceEquals

また、それが正しければ、構造体で static キーワードを使用する意味はありますか?

ここでの主なポイントは、これをシングルトンにすることではありません。API を単純化して、実質的に色の定数値を取得することです:Colors.RedまたはColors.Green. これが静的でない場合は、毎回手動で「赤」の色を作成する必要があります。Colorsこの場合のプロパティは、事実上、クラスの見栄えの良いファクトリ メソッドです。

于 2013-01-03T00:03:14.827 に答える