SHOJI's Code
 仕事や趣味で書いた各種言語のプログラミングコード(エクセルVBA,PHP,C/C++/C#,JavaScript等)、その他雑記。
2017.10<<123456789101112131415161718192021222324252627282930>>2017.12
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

仕事でC#でプログラミングするときに、よく string.Format メソッドなどで文字列を書式化することがよくあるが、論理型(Boolean)は書式化しても "True" か "False" にしか書式化されない。だから string.Format などで、
string.Format("{0}", b ? "1" : "0");

などとせざるを得ない。特に問題にならないケースも多いが、書式文字列をパラメータ化した場合など、できればboolはboolのまま渡して書式設定でどうにかしたい。

アプローチは2つ。

IFormattableインターフェイスを実装するクラスを作り、その ToString で書式化をサポートする。後述の FormattableBooleanクラスでは以下のようになる。
bool b = true;
FormattableBoolean fb = b;
string s = fb.ToString("{0:Y}");


IFormatProviderとICustomFormatterを実装したクラスを作り、string.Format にカスタム書式設定とする。後述のBooleanFormatterクラスでは以下のように使用する。
string s = string.Format(new BooleanFormatter(), "{0}", b);



public class FormattableBoolean : IFormattable
{
bool b;

public FormattableBoolean(object value) {
b = Convert.ToBoolean(value);
}


public override bool Equals(object obj)
{
if (obj is FormattableBoolean) return b.Equals((bool)obj);
return b.Equals(obj);
}

public override int GetHashCode()
{
return b.GetHashCode();
}

public override string ToString()
{
return b.ToString();
}

public static implicit operator bool(FormattableBoolean fb) {
return fb.b;
}
public static implicit operator FormattableBoolean(bool b) {
return new FormattableBoolean(b);
}

public static bool operator true(FormattableBoolean fb) {
return fb.b;
}
public static bool operator false(FormattableBoolean fb) {
return !fb.b;
}

public static bool operator !(FormattableBoolean fb) {
return new FormattableBoolean(!fb.b);
}

public static bool operator &(FormattableBoolean fb1, FormattableBoolean fb2) {
return fb1.b && fb2.b;
}
public static bool operator |(FormattableBoolean fb1, FormattableBoolean fb2) {
return fb1.b || fb2.b;
}


public string ToString(string format, IFormatProvider formatProvider)
{
if (format == null || format==string.Empty) return ToString();

switch (format) {
case "Y": return b ? "YES" : "NO";
case "y": return b ? "yes" : "no";
case "O": return b ? "ON" : "OFF";
case "o": return b ? "on" : "off";
case "0": return b ? "1" : "0";

default:
string[] pair = format.Split(';');
string st = pair.Length>0 ? pair[0] : string.Empty;
string sf = pair.Length>1 ? pair[1] : string.Empty;
return b ? st : sf;
}
}
}

public class BooleanFormatter : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
return formatType==typeof(ICustomFormatter) ? this : null;
}

public string Format(string format, object arg, IFormatProvider formatProvider)
{
if (arg is bool) arg = new FormattableBoolean(arg);

if (arg is IFormattable) {
return ((IFormattable)arg).ToString(format, formatProvider);
}
else if (arg!=null) {
return arg.ToString();
}

return string.Empty;
}
}

テーマ:プログラミング - ジャンル:コンピュータ
コメント
この記事へのコメント
コメントを投稿する

管理者にだけ表示を許可する
トラックバック
この記事のトラックバックURL
この記事へのトラックバック
copyright © 2004-2006 SHOJI, Powered By FC2ブログ all rights reserved.
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。