Xml読み込みの設計をしているとき、Xmlクラスのメンバ変数は全部string型にした方がいいのでは?と思いました。
タグの要素の内容をメンバ変数に変換するとき、例外が発生しないからです。
XmlSerializerを使用すれば、Xmlクラスのメンバ変数の型はint、bool も可能です。それでも、あえて全部string のほうがいいのでは?と思いました。
どうするのが正解なのか?
XmlSerializerを使用すると、XMLファイルの内容を対応するクラスオブジェクトに相互変換できます。今後、クラスオブジェクトの型をXmlクラスと呼びます。
- Windows10
- Microsoft Visual Studio Community2022
- .NET 6
Xmlクラスのメンバ変数を全部string型
int型やbool型で読み込めるものも全部string 型で読み込みます。サンプルのAdministratorXmlクラスは以下のようになります。
namespace XmlProject
{
/// <summary>
/// 管理者Xml
/// </summary>
public class AdministratorXml : UserXml
{
/// <summary>ID</summary>
public string? id;
/// <summary>パスワード</summary>
public string pass;
/// <summary>年齢</summary>
public string age;
/// <summary>年齢表示判定</summary>
public string isViewAge;
/// <summary>役職</summary>
public string position;
public AdministratorXml()
{
id = null;
pass = "abc";
age = "30";
isViewAge = "false";
position = "未設定";
}
}
}
年齢、年齢表示判定は、それぞれint型、bool型で書くことができますが、あえてstring型で書きます。
メリット
メリットは、タグの要素の内容 → メンバ変数の変換で例外が発生しないことです。
例えば、年齢がタグの要素の内容が文字列の場合
<age>abc</abc>
Xmlクラスのメンバ変数ageの型がstring となっていたなら、string age = “abc” と読み込むことができます。
public string age;
ところが、int型となっていた場合、読み込み時に例外が発生します。
public int age;
Xmlのタグの要素が不正値であってもとりあえず読み込むことができます。
デメリット
デメリットは、型変換の処理を別で行う必要があることです。年齢ageは、int型として判定処理をしたいので、結局intの変換は必要です。
一番いいのは、Xmlクラスのメソッドに追記することでしょうか?
namespace XmlProject
{
/// <summary>
/// 管理者Xml 抜粋
/// </summary>
public class AdministratorXml : UserXml
{
/// <summary>年齢</summary>
public string age;
public AdministratorXml()
{
age = "30";
}
public int ParseAge()
{
int ret;
return int.TryParse(age, out ret) ? ret : int.Parse(age);
}
}
}
ただ、Xmlクラスのメンバ変数はpublicとしなければいけません。なので、ParseAgeメソッドは外部のクラスでも書けます。カプセル化の観点では、弱いです。
Xmlクラスのメンバ変数の型を指定
この場合のメリット、デメリットは、先ほどの裏返しとなります。
メリット
型変換の処理を行う必要がないことです。先ほどのageメンバ変数の例だと、string→intの変換は、XmlSerializerが行います。
デメリット
タグの要素の内容を読み込んだとき、例外が発生する可能性があることです。
先ほどの例で、ageタグの要素の内容が”abc” だった場合は、XmlSerializer でintに変換できませんInvalidOperationException をthrow します。
しかも、どのメンバ変数の読み込みで例外が発生したかの確認できません。InvalidOperationException クラスオブジェクトのMessageは、
There is an error in XML document (9, 8).
と出力されるだけで、かなり分かりにくいです。
結局どっちがいいのか?
どっちもメリット、デメリットがありますが、ぼくは前者を選択しました。
パラメータを全部string型にするデメリットに、型変換の処理を別で行う必要があること と書きました。ですが、Xmlクラスは、publicの制限があり、そのまま使うのはあまりよろしくありません。
結局、Xmlクラスを別クラスにする必要があります。そのとき、型変換を行えばよいと思いました。
まとめ
C# のXMLファイル読み込みにおいて、Xmlクラスのメンバ変数の型は全てstring型にすべきというテーマで書きました。
- すべてstring型
- 型を指定する
どちらの方法もメリット、デメリットがあります。どちらを選ぶかは設計方針で決めた方がいいです。
コメント