public static string ToString(this object anObject, string aFormat)
{
return ToString(anObject, aFormat, null);
}
public static string ToString(this object anObject, string aFormat, IFormatProvider formatProvider)
{
var sb = new StringBuilder();
var type = anObject.GetType();
var reg = new Regex(@"({)([^}]+)(})", RegexOptions.IgnoreCase);
MatchCollection mc = reg.Matches(aFormat);
int startIndex = 0;
foreach (Match m in mc)
{
var g = m.Groups[2];
int length = g.Index - startIndex - 1;
sb.Append(aFormat.Substring(startIndex, length));
string toGet;
var toFormat = String.Empty;
int formatIndex = g.Value.IndexOf(":");
if (formatIndex == -1)
{
toGet = g.Value;
}
else
{
toGet = g.Value.Substring(0, formatIndex);
toFormat = g.Value.Substring(formatIndex + 1);
}
PropertyInfo retrievedProperty = type.GetProperty(toGet);
Type retrievedType = null;
object retrievedObject = null;
if (retrievedProperty != null)
{
retrievedType = retrievedProperty.PropertyType;
retrievedObject = retrievedProperty.GetValue(anObject, null);
}
else
{
FieldInfo retrievedField = type.GetField(toGet);
if (retrievedField != null)
{
retrievedType = retrievedField.FieldType;
retrievedObject = retrievedField.GetValue(anObject);
}
}
if (retrievedType != null)
{
string result;
if (toFormat == String.Empty)
{
result = retrievedObject.ToString();
}
else
{
if (retrievedType.IsNullableType())
{
retrievedType = Nullable.GetUnderlyingType(retrievedType);
}
result = retrievedType.InvokeMember("ToString",
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.InvokeMethod |
BindingFlags.IgnoreCase,
null, retrievedObject, new object[] {toFormat, formatProvider}) as string;
}
sb.Append(result);
}
else
{
sb.Append("{");
sb.Append(g.Value);
sb.Append("}");
}
startIndex = g.Index + g.Length + 1;
}
if (startIndex < aFormat.Length)
{
sb.Append(aFormat.Substring(startIndex));
}
return sb.ToString();
}
public static bool IsNullableType( this Type theType )
{
return (theType.IsGenericType && theType.GetGenericTypeDefinition().Equals(typeof (Nullable<>)));
}