WithVar
Improve readability of string.Format
Source
/// <summary>
/// ex) "{a}, {a:000}, {b}".WithVar(new {a, b});
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="str">A composite format string (equal string.Format's format)</param>
/// <param name="arg">class or anonymouse type</param>
/// <returns></returns>
public static string WithVar<T>(this string str, T arg) where T : class
{
var type = typeof(T);
foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
{
if (!(member is FieldInfo || member is PropertyInfo))
continue;
var pattern = @"\{" + member.Name + @"(\:.*?)?\}";
var alreadyMatch = new HashSet<string>();
foreach (Match m in Regex.Matches(str, pattern))
{
if (alreadyMatch.Contains(m.Value)) continue; else alreadyMatch.Add(m.Value);
string oldValue = m.Value;
string newValue = null;
string format = "{0" + m.Groups[1].Value + "}";
if (member is FieldInfo)
newValue = format.With(((FieldInfo)member).GetValue(arg));
if (member is PropertyInfo)
newValue = format.With(((PropertyInfo)member).GetValue(arg));
if (newValue != null)
str = str.Replace(oldValue, newValue);
}
}
return str;
}
public static string With(this string str, params object[] param)
{
return string.Format(str, param);
}
Example
int count = 10;
var message = "{count} Rows Deleted!".WithVar(new {count});
// message : 10 Rows Deleted!
var message2 = "{count:00000} Rows Deleted!".WithVar(new {count});
// message2 : 00010 Rows Deleted!
var query = "select * from {TableName} where id >= {Id};".WithVar(new {TableName = "Foo", Id = 10});
// query : select * from Foo where id >= 10;