Stringの名前とデフォルト値を持つ定数

投稿日 : 2008年7月5日 23:39

 Windows Live Writer SDK関連のための話しです。WLWのプラグイン作成時に IProperties というインタフェースが出てきます。これは次のようにプラグイン固有のまたはプラグインにより挿入したコンテンツ固有の情報を取得・設定するために用意されています。

Dim foo = Options.GetString("Foo", "foo")
Options.SetString("Foo", "bar")

 OptionsがIProperties型。情報を取得する場合、GetString(名前, デフォルト値)と呼び出します。設定する場合は、SetString(名前, 設定値)となります。基本的な型についてはそれぞれGetIntなどのメソッドが用意されてます。

 このIPropertiesを上のようにそのまま使用すると大量に文字列リテラルが出てきます。リテラルじゃないのは設定値となる"bar"のところだけ。単純に解決するには全部定数に置き換えます。

Const Foo As String = "Foo"
Const FooDefaultValue As String = "foo"

 するとこうなる。単純で良いのかもしれないけれど、Fooという名前にFooと値をいれてる、この例ではFooひとつだけだけど複数の設定項目が出た場合にグループとして扱えない、FooとFooDefaultValueは意味的にはペアとして扱いたいなど気になる点が出てきます。

 文字列の列挙体があればいいのだけど、それは言語的にできません。ただし、じゃんぬさんが昔に文字列の列挙体というエントリを投稿されてます。詳しくはそちらで。私もこれを参考にして、ペアの部分についても考えて出たコードが以下。

 まずは、値の設定・取得するところは次のようになって、

Dim foo = Options.GetString(FooPluginOptions.Foo.Name, FooPluginOptions.Foo.DefaultValue)
Options.SetString(FooPluginOptions.Foo.Name, "bar")

設定項目ごとに記述する部分は次のようになりました。

Public NotInheritable Class FooPluginOptions
    Public Shared ReadOnly Foo As New Item(Of String)("foo")
    Public Shared ReadOnly Bar As New Item(Of Integer)(100)

    ' (略 見てはいけない部分)

End Class

設定項目ごとに項目の型とデフォルト値を指定した、Itemというオブジェクトを作ってます。

 隠された部分は以下。FooPluginOptionsの中にあるコードです。うーむ。設定項目のグループごとに書くとなると、どんだけーって感じですね。Itemクラスは外に出しても問題ありませんが、コンストラクタ内のコードは必要になり親クラスとして切り出すと動作しなくなってしまいます。

 設定値の名前とそのデフォルト値のペアとしてItemクラスを作っています。プロパティとしてReadOnlyのNameとDefaultValueを持ってます。ToStringをオーバーライドしてNameを返すようにしているので Strict Offの場合はNameプロパティ要らず(私は常にStrict Onだけど)。Sharedなコンストラクタ内で自分自身のフィールドを取得してItemオブジェクトのNameプロパティにフィールド名そのままを設定してます。Private変数を書き変えてます。

Public NotInheritable Class Item(Of T)
    Private _name As String
    Public ReadOnly Property Name() As String
        Get
            Return _name
        End Get
    End Property

    Private _defaultValue As T
    Public ReadOnly Property DefaultValue() As T
        Get
            Return _defaultValue
        End Get
    End Property

    Public Sub New(ByVal defaultValue As T)
        _defaultValue = defaultValue
    End Sub

    Public Overrides Function ToString() As String
        Return _name
    End Function
End Class

Shared Sub New()
    Dim fieldsInfo = GetType(BasePropertyItems).GetFields( _
        BindingFlags.DeclaredOnly Or _
        BindingFlags.GetField Or _
        BindingFlags.Instance Or _
        BindingFlags.Public Or _
        BindingFlags.Static Or _
        BindingFlags.FlattenHierarchy)

    For Each info In fieldsInfo
        Dim item = info.GetValue(Nothing)
        item.GetType.InvokeMember( _
            "_name", _
            BindingFlags.SetField Or BindingFlags.NonPublic Or BindingFlags.Instance, _
            Nothing, _
            item, _
            New Object() {info.Name}, _
            Nothing, Nothing, Nothing)
    Next
End Sub

 どんな感じですかねぇ。ナイスな方法があれば教えてください。

フィードバック

# IPropertiesと拡張メソッド

2008/07/06 0:00 by katamari.wankuma.com
IPropertiesと拡張メソッド

# bYCGpflGaPvhvlVWCu

2011/09/28 16:40 by http://oemfinder.com
XvV2aD Author, keep doing in the same way..!

# IvcUfhWxiRhgFTUHmn

2011/10/21 22:04 by http://www.epotenzmittel.com/
Hello! Read the pages not for the first day. Yes, the connection speed is not good. How can I subscribe? I would like to read you in the future!...

# JEEqvLpEvqo

2011/11/02 5:24 by http://www.pharmaciecambier.com/
Can be also this issue because the truth can be achieved only in a dispute :D

# QizBWlwtMWMrlLffV

2011/11/08 16:26 by http://www.disfuncion-erectil.org
Scribbler, give me a student's record-book!)))

# npByAQDENFqrMnuVzHL

2011/11/09 6:39 by http://www.farmaciaunica.com/
Yeah, now it's clear !... And firstly I did not understand very much where there was the link with the title itself !!...

# xQaftdoxbmOmfM

2011/11/16 4:39 by http://www.hooksandlattice.com/garden-table.html
Current blog, fresh information, I read it from time to time!!...
コメントの入力
タイトル
 
名前
 
Url
コメント