DictionaryのMerge

Public Shared Function MergeDictionary(Of TKey, TValue) _
   (ByVal first As Dictionary(Of TKey, TValue), _
    ByVal second As Dictionary(Of TKey, TValue)) As Dictionary(Of TKey, TValue)
    If (second Is Nothing) Then
        Return first
    End If
    If (first Is Nothing) Then
        first = New Dictionary(Of TKey, TValue)()
    End If

    For Each kv As KeyValuePair(Of TKey, TValue) In second
        If (first.ContainsKey(kv.Key)) Then
            first(kv.Key) = kv.Value
        Else
            first.Add(kv.Key, kv.Value)
        End If
    Next
    Return first
End Function

RealProxyが悩ましい

アスペクト指向のアプローチが向いている要件があって、調査中。.NETで用意されているRealProxyを使えば実現可能かと思われましたが、落とし穴があって中断中。

現時点での理解では、RealProxyを使ってメソッドに介入できるのは別クラス間の呼び出しのみで、同クラスのPrivateメソッドでは、それが効かない。このためだけに下請けクラスを作るという案もあるが、そこまで踏み切れない。

 

ApplicationSettingsBaseが悩ましい

アプリケーションの設定を保存したい要件があって調査しました。
.NET Frameworkで用意されているApplicationSettingsBaseクラスが使えそうですが、いくつか難点があります。このままでは自作になりそう。

  • 複数のアプリケーションで一つの設定情報を使いたい。もちろん単なるXMLとしてなら、複数アプリからでも読み書きは可能だが、それではあんまり。
  • 設定ファイルの場所を自由に変えたい。中身を直に加工することもあり得る。
  • 「Update」メソッドが期待より非力。結局はバージョン管理は自前でやることになりそう。

カスタムコントロールにデザイナ編集時のデフォルトを与える

Imports System.ComponentModel

<System.ComponentModel.Designer(GetType(MyButtonDesiner))> _
Public Class MyButton
    Inherits Button

End Class

Public Class MyButtonDesiner
    Inherits System.Windows.Forms.Design.ControlDesigner

    Public Overrides Sub InitializeNewComponent(ByVal defaultValues As System.Collections.IDictionary)
        MyBase.InitializeNewComponent(defaultValues)
        Dim ctl As MyButton = DirectCast(Me.Control, MyButton)
        ctl.Text = ""
    End Sub

End Class

Enumをコンボボックスに設定

「Enumに属性で日本語表示を付加」を前提として

    Private Sub EnumToComboBox(ByVal enumType As Type, ByRef cmb As ComboBox)
        Dim defineTable As DataTable = New DataTable()
        defineTable.Columns.Add("display", GetType(String))
        defineTable.Columns.Add("value", enumType)

        For Each enumName As String In [Enum].GetNames(enumType)
            Dim row As DataRow = defineTable.NewRow()
            row("display") = EnumJpAttribute.ToStringJp([Enum].Parse(enumType, enumName))
            row("value") = [Enum].Parse(enumType, enumName)
            defineTable.Rows.Add(row)
        Next
        defineTable.AcceptChanges()

        cmb.DataSource = defineTable
        cmb.DisplayMember = "display"
        cmb.ValueMember = "value"
        cmb.DropDownStyle = ComboBoxStyle.DropDownList  'ユーザーのテキスト編集を許可しない
    End Sub

Enumに属性で日本語表示を付加

'属性クラス
<AttributeUsage(AttributeTargets.Field, AllowMultiple:=False, Inherited:=False)> _
Public Class EnumJpAttribute
    Inherits Attribute

    Private _literal As String

    Public Sub New(ByVal literal As String)
        _literal = literal
    End Sub

    Public Shared Function ToStringJp(ByVal value As Object) As String
        Dim enumType As Type = value.GetType()
        Dim enumName As String = [Enum].GetName(enumType, value)
        Dim fi As FieldInfo = enumType.GetField(enumName)
        Dim attrs As EnumJpAttribute() = DirectCast( _
          fi.GetCustomAttributes(GetType(EnumJpAttribute), False), EnumJpAttribute())
        Return attrs(0)._literal
    End Function
End Class

'Enum定義
Public Enum SexType As Integer
    <EnumJpAttribute("男性")> _
    Male
    <EnumJpAttribute("女性")> _
    Female
End Enum

'使用する側
EnumJpAttribute.ToStringJp(SexType.Male)