より良いエンジニアを目指して

1日1つ。良くなる!上手くなる!

System.Data.DataColumnの列名は条件的に大文字小文字を区別する

レガシーコードを見ていたらDataTableのDataColumnなのですが、列名が大文字になったり、小文字になったりしている箇所がありました。

あれ、なんでこれ、動くんだ? 大文字と小文字区別しないわけなんてあるか?

forums.asp.net

どうやらDataTableのDataColumnはConditionally(条件的に)Case Sensitive(大文字と小文字を区別する)です。

気を利かせてくれるのか、大文字と小文字を区別する必要のある列を二つ以上持つと区別するようになります。

例えばCodeという列しかない場合は、codeで指定してもCODEで指定しても認識します。

ただし、CodeとCODEという二つの列を持つと、大文字小文字を正しく指定しないと例外となります。

using System;
using System.Data;
                    
public class Program
{
    public static void Main()
    {
        var t = new DataTable(); 
        var c = new DataColumn(); 
        c.DataType = Type.GetType("System.String");
        c.ColumnName = "CODE"; 
        t.Columns.Add(c); 
        var view = t.DefaultView; 
        var row = view.AddNew(); 
        row["code"] = "test"; 
        row.EndEdit(); 
        Console.WriteLine(t.Rows[0]["coDe"]);
    }
}

f:id:rimever:20210303192420p:plain
これは成功する

ただし、以下のようにすると失敗します。

using System;
using System.Data;
                    
public class Program
{
    public static void Main()
    {
        var t = new DataTable(); 
        var c = new DataColumn(); 
        c.DataType = Type.GetType("System.String");
        c.ColumnName = "CODE"; 
        t.Columns.Add(c); 
        
        c = new DataColumn(); 
        c.DataType = Type.GetType("System.String");
        c.ColumnName = "CODe"; 
        t.Columns.Add(c); 

        var view = t.DefaultView; 
        var row = view.AddNew(); 
        row["code"] = "test"; 
        row.EndEdit(); 
        Console.WriteLine(t.Rows[0]["coDe"]);
    }
}

f:id:rimever:20210303192646p:plain
The given name 'code' matches at least two names in the collection object with different cases, but does not match either of them with the same case

とはいえ、大文字小文字を区別しないからといって甘えず、こうした列名はマジックナンバーにせず、定数化するべきでしょう。

なので、ボーイスカウト精神で、修正する箇所は前よりも綺麗にするという心持ちで定数化したのでした。