WithVar

/// <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;

Description

Improve readability of string.Format

Details

Double click on the code to select all.

 

;