28. mai 2009 22:38
lea
Conditional formatting of System.Boolean
I had a small challenge today (yay!) when trying to localize some strings based on a boolean in the domain.
Boolean's ToString() methods only returns the static strings "True" and "False", hence String.Format(MyLocalizedString, true) cannot return "ja", "sant", or any other norwegian representations of the bool true.
Enter the FormattableBool which interprets a conditional operator in the format string. :)
public struct FormattableBool : IFormattable
{
static FormattableBool fbTrue = new FormattableBool(true);
static FormattableBool fbFalse = new FormattableBool(false);
bool value;
public FormattableBool(bool value)
{
this.value = value;
}
#region IFormattable Members
public string ToString(string format, IFormatProvider formatProvider)
{
if (format.StartsWith("LC"))
{
if (!(format.Contains("?") && format.Contains(":")))
throw (new InvalidOperationException("Format does not contain ? and :"));
string[] formatParts = format.Split("?:".ToCharArray());
if (formatParts.Length != 3)
throw (new InvalidOperationException("Format is invalid"));
return value ? formatParts[1] : formatParts[2];
}
else
return ToString();
}
#endregion
public static implicit operator FormattableBool(bool x)
{
return x ? fbTrue : fbFalse;
}
public static explicit operator bool(FormattableBool x)
{
return x.value;
}
public override bool Equals(object obj)
{
if (obj is bool)
return value.Equals(obj);
if (obj is FormattableBool)
return value.Equals(((FormattableBool)obj).value);
return false;
}
public override int GetHashCode()
{
return value.GetHashCode();
}
}
Turns out it can be used in several forms, where my favorite must be (FormattableBool)true.
[TestMethod]
public void TestFormattableBoolFormatting()
{
bool yep = true;
bool nope = false;
FormattableBool fyep = true;
FormattableBool fnope = false;
Assert.AreEqual(yep, fyep);
Assert.AreEqual(nope, fnope);
Assert.AreEqual("ja", String.Format("{0:LC?ja:nei}", fyep));
Assert.AreEqual("nei", String.Format("{0:LC?ja:nei}", fnope));
Assert.AreEqual("yep", String.Format("{0:LC?yep:nope}", (FormattableBool)true));
Assert.AreEqual("nope", String.Format("{0:LC?yep:nope}", (FormattableBool)false));
}
Filed under: C#, Utilities