When Justin submitted this C# code, he knew what line to include in the subject line of the email to get our attention:
if (String.Empty == null) GC.KeepAlive(string.Empty);
String
is the string datatype. string
is just an alias to that type, used to make the code look more like C. Empty
is a constant that represents an empty string. And GC represents the garbage collector- if the Empty string constant has somehow become null, prevent that constant which is currently not pointing at anything from being garbage collected.
That’s the cleanest, most easy to understand line of code in this entire module.
Justin’s co-worker wanted to convert built in types to Strings, and back, and he wanted to do this in the most enterprise-y way possible. Se he created:
public static class StructT
{
/// <summary>Convert the given value type fo a string</summary>
/// <typeparam name="TYPE">The type of the value to convert</typeparam>
/// <param name="value">The value to convert</param>
/// <returns>The string representation of the value, or null if HasValue is false</returns>
/// <remarks>Only the types DateTime, Int32, Int64, Decimal, Single, Double, Char, Byte, Guid, Enum, Boolean are supported</remarks>
public static string ToString<TYPE>(TYPE? value) where TYPE : struct
{
return StructT<TYPE>._ToString(value);
}
/// <summary>Convert the given value type fo a string</summary>
/// <typeparam name="TYPE">The type of the value to convert</typeparam>
/// <param name="value">The value to convert</param>
/// <returns>The string representation of the value</returns>
/// <remarks>Only the types DateTime, Int32, Int64, Decimal, Single, Double, Char, Byte, Guid, Enum, Boolean are supported</remarks>
public static string ToString<TYPE>(TYPE value) where TYPE : struct
{
return StructT<TYPE>._ToString(value);
}
}
This static class depends on a generic class with the same name. The underlying class has one of those delightfully clear constructors:
static StructT()
{
_formatProvider = System.Globalization.CultureInfo.InvariantCulture;
_ourType = typeof(TYPE);
if (String.Empty == null) GC.KeepAlive(string.Empty);
else if (_ourType == typeof(DateTime)) { _TryParse = MkDeP<DateTime>(ParseDate); _ToString = MkDeS<DateTime>(StringizeDate); }
else if (_ourType == typeof(Int32)) { _TryParse = MkDeP<Int32>(ParseInt32); _ToString = MkDeS<Int32>(StringizeInteger); }
else if (_ourType == typeof(Int64)) { _TryParse = MkDeP<Int64>(ParseInt64); _ToString = MkDeS<Int64>(StringizeInteger); }
else if (_ourType == typeof(Decimal)) { _TryParse = MkDeP<Decimal>(ParseDecimal); _ToString = MkDeS<Decimal>(StringizeFloat); }
else if (_ourType == typeof(Single)) { _TryParse = MkDeP<Single>(ParseSingle); _ToString = MkDeS<Single>(StringizeFloat); }
else if (_ourType == typeof(Double)) { _TryParse = MkDeP<Double>(ParseDouble); _ToString = MkDeS<Double>(StringizeFloat); }
else if (_ourType == typeof(Char)) { _TryParse = MkDeP<Char>(ParseChar); _ToString = StringizeOther; }
else if (_ourType == typeof(Byte)) { _TryParse = MkDeP<Byte>(ParseByte); _ToString = MkDeS<Byte>(StringizeInteger); }
else if (_ourType == typeof(Guid)) { _TryParse = MkDeP<Guid>(ParseGuid); _ToString = StringizeOther; }
else if (_ourType == typeof(Boolean)) { _TryParse = MkDeP<Boolean>(ParseBool); _ToString = MkDeS<Boolean>(StringizeBoolean); }
else if (_ourType.IsEnum) { _TryParse = ParseEnum; _ToString = StringizeOther; }
else throw new InvalidOperationException();
}
And MkDeP
and MkDeS
?
private static Converter<string, TYPE?> MkDeP<UUUU>(System.Converter<string, UUUU?> loww) where UUUU : struct { return (System.Converter<string, TYPE?>)(Delegate)loww; }
private static Converter<TYPE?, string> MkDeS<UUUU>(System.Converter<UUUU?, string> loww) where UUUU : struct { return (System.Converter<TYPE?, string>)(Delegate)loww; }
I just like seeing datatypes named UUUU
.
In addition to these methods, there’s a set of methods to Stringize
and Parse
each primitive data-type. For example, StringizeDate
:
private static string StringizeDate(DateTime? value)
{
if (!value.HasValue)
return null;
var s = String.Format(_formatProvider, "{0:yyyy}-{0:MM}-{0:dd}T{0:HH}:{0:mm}:{0:ss}", value.Value);
if (value.Value.Kind == DateTimeKind.Utc) s += "Z";
return s;
}
That is actually sane and makes good use of the String format library. Contrast that to ParseDate
, which is what happens when someone wants to reinvent the wheel:
private static DateTime? ParseDate(string raw)
{
// YYYY-MM-DDTHH:MM:SSZ
if (String.IsNullOrEmpty(raw)) return null;
bool utcInd = false, lenGood;
if (raw.Length == 10) raw += "T00:00:00";
if (raw.Length == 20 && (raw[19] == 'Z' || raw[19] == 'z')) { utcInd = true; lenGood = true; } else lenGood = raw.Length == 19;
if (!lenGood) throw new FormatException();
int year, month, day, hour, minute, second;
try
{
year = Int32.Parse(raw.Substring(0, 4), _formatProvider);
month = Int32.Parse(raw.Substring(5, 2), _formatProvider);
day = Int32.Parse(raw.Substring(8, 2), _formatProvider);
hour = Int32.Parse(raw.Substring(11, 2), _formatProvider);
minute = Int32.Parse(raw.Substring(14, 2), _formatProvider);
second = Int32.Parse(raw.Substring(17, 2), _formatProvider);
}
catch { throw new FormatException(); }
return new DateTime(year, month, day, hour, minute, second, utcInd ? DateTimeKind.Utc : DateTimeKind.Unspecified);
}
The .NET DateTime object has a built in Parse
method which can parse a date given a format string.
This is ugly, and mostly useless code. .NET already has methods that make it easy to turn data into strings and back. So what’s the real WTF? The real WTF is this: the original developer was allergic to letting native data-types cross module boundaries. Every function accepted all of its parameters as strings. Every function returned strings. Every function depended on this class to interact with values that could easily have been passed in natively.