C# string template

摘要:C# string template

這個的 C#版本


/// "p1={p1}, p3={p3.date:yyyy-MM-dd}".FormatByObject(new { p1 = 1, p3 = new { date = DateTime.UtcNow } })
public static string FormatByObject(this string template, object obj, bool clearIfNull = false)
{
	return FormatStringByObject(template, obj, clearIfNull);
}

/// FormatStringByObject("p1={p1}, p3={p3.date:yyyy-MM-dd}", new { p1 = 1, p3 = new { date = DateTime.UtcNow } })
private static string FormatStringByObject(string template, object obj, bool clearIfNull)
{
	Regex reg = new Regex(@"{([^}]+)}");
	var matches = reg.Matches(template);
	foreach (var match in matches)
	{
		template = InjectPropertyValue(template, match.ToString(), obj, clearIfNull);
	}

	return template;
}
private static string InjectPropertyValue(string template, string match, object obj, bool clearIfNull)
{
	string property = match.Substring(1, match.Length - 2);// 去大括號 {p1} → p1

	var splitProperty = property.Split(new char[] { ':' });
	object resultObj = GetProperty(splitProperty[0], obj);
	if (resultObj != null)
	{
		if (splitProperty.Count() == 2 && resultObj is DateTime)
		{
			template = template.Replace(match, ((DateTime)resultObj).ToString(splitProperty[1]));
		}
		else
		{
			template = template.Replace(match, resultObj.ToString());
		}
	}
	else if (clearIfNull)
	{
		template = template.Replace(match, string.Empty);
	}

	return template;
}
private static object GetProperty(string property, object obj)
{
	string[] deepProperties = property.Split(new char[] { '.' });
	object deepObj = obj;
	foreach (var deepProperty in deepProperties)
	{
		if (deepObj == null)
		{
			break;
		}
		var innerProperty = deepObj.GetType().GetProperties()
			.FirstOrDefault(tmpProprety => tmpProprety.Name == deepProperty);
		deepObj = innerProperty == null ? null : innerProperty.GetValue(deepObj);
	}
	return deepObj;
}

還是比較習慣 JavaScript的 reflection,隨便亂寫都能跑(有時能跑有時出錯又是另一個故事了XD)