初期値 != 既定値???

初期値と既定値は同じだと勝手に思い込んでいた。

しかし、違うのねん!! というお話し。


初期値と既定値、そしてそれに関連して初期化が絡み、私の頭の中で適当に解釈されていたこれらを整理したい。

C# 初期値」と検索すると何故か二番目に表示されるのが既定値の一覧表 (C# リファレンス)

読んで字のごとく、既定値の一覧だ。
だが、初期値と既定値は必ずしも一致しない

例えば、こんなクラスがあったとする。

class Hoge
{
    public int IntValue { get; set; }
}
このHogeクラスのインスタンスを生成すると、IntValueにはint型の既定値である「0」が入る。

つまり、初期化を明示的に行っていないIntValueプロパティの初期値はその型の既定値となるワケだ。



では、IntValueプロパティの初期化を行う。
初期値を1とする。

パターン1:
class Hoge1
{
    public Hoge1()
    {
        this.IntValue = 1;
    }

    public int IntValue { get; set; }
}


パターン2:
class Hoge2
{
    private int intValue;

    public Hoge2()
    {
        intValue = 1;
    }

    public int IntValue
    {
        get
        {
            return intValue;
        }
        set
        {
            intValue = value;
        }
    }
}


パターン3:
class Hoge3
{
    private int intValue = 1;

    public int IntValue
    {
        get
        {
            return intValue;
        }
        set
        {
            intValue = value;
        }
    }
}
分かりやすいようにint型の既定値「0」ではない値「1」を設定した。

どれもやっていることに大差はない。
ここで重要なのは初期値を設定したことにある。
最初に何らかの値を設定することを初期化と言い、初期化によって設定された値が初期値である。

何だか当り前のことを書いてて若干アホらしくなってきた...

初期値と既定値が同じ値となる可能性もあるが、初期値と既定値が同じ場合の初期化の必要性をここで四の五の言うつもりはないのでそれに関してはスルー。


「何で私が混乱してしまったのか?」を最初に説明すべきだったかも知れないが、今更に述べるが、DefaultValueAttributeが何モノなのか?分からなくなってしまったから。
説明には「プロパティの既定値を指定します。」とある。

私は勝手に「これを使えば初期化しなくてもその値が設定される?」と思ったのだが、どうやらそういうことではないようだ。

例えば、こんなクラスがあったとする。
class Foo
{
    public Foo()
    {
        //this.IntValue = 100;
        //this.BoolValue = true;
        //this.ColorValue = Color.White;
    }

    [DefaultValue(typeof(int), "100")]
    public int IntValue { get; set; }

    [DefaultValue(typeof(bool), "True")]
    public bool BoolValue { get; set; }

    [DefaultValue(typeof(Color), "White")]
    public Color ColorValue { get; set; }
}
このFooクラスのインスタンスを生成しても、そのプロパティの値はそれぞれの型の既定値のままだった。

ん~~ (-。-;)y-゜゜゜

やはり初期化しないとダメなのか?

引用:解説
任意の値を指定してDefaultValueAttributeを作成できます。通常、メンバの既定値はその初期値になります。ビジュアル デザイナでは、その既定値を使用してメンバの値をリセットできます。コード ジェネレータでも、既定値を使用して、メンバに対してコードを生成する必要があるかどうかを判断できます。

なんかIDEが勝手に吐くコードに関係ありそう。
逆に言えば、コンソールアプリでは無意味かも...?!


さらに引用:
private bool myVal=false;

[DefaultValue(false)]
public bool MyProperty {
   get {
      return myVal;
   }
   set {
      myVal=value;
   }
}
あれ?ちゃっかり初期化してる(-_-;)


半分やけくそでコンストラクタを書き換えてみる。
class Foo
{
    public Foo()
    {
        //書き加えた処理
        foreach (PropertyInfo fi in typeof(Foo).GetProperties())
        {
            AttributeCollection attrs =
                TypeDescriptor.GetProperties(this)[fi.Name].Attributes;
            fi.SetValue(
                this,
                ((DefaultValueAttribute)attrs[typeof(DefaultValueAttribute)]).Value,
                null);
        }
    }

    [DefaultValue(typeof(int), "100")]

    public int IntValue { get; set; }

    [DefaultValue(typeof(bool), "True")]
    public bool BoolValue { get; set; }

    [DefaultValue(typeof(Color), "White")]
    public Color ColorValue { get; set; }
}
コンストラクタでDefaultValueに設定した値で初期化されるようにしてみた。

実際に使ってみる。
Foo foo = new Foo();

Console.WriteLine("IntValue:{0}\nBoolValue:{1}\nColorValue:{2}\n",
    foo.IntValue,
    foo.BoolValue,
    foo.ColorValue);

//Output
//IntValue:100
//BoolValue:True
//ColorValue:Color [White]

これでイイとは思ってないけど、これでおわり。

1 Comments:

匿名 さんのコメント...

DefaultValueAttributeはIDEで既定値以外の場合は太字にするとか、コード生成するかしないかを判断するために使用されています。

Recent Posts