Skip to content

Instantly share code, notes, and snippets.

@zaus
Created September 21, 2012 18:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zaus/3763138 to your computer and use it in GitHub Desktop.
Save zaus/3763138 to your computer and use it in GitHub Desktop.
C# Named token replacement as an alternative to the numerical tokens of String.Format - yet another attempt at performance
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
/// via original discussion http://haacked.com/archive/2009/01/14/named-formats-redux.aspx
namespace Haacked.StringLib {
/// <summary>
/// Extension string methods for named token replacement
/// </summary>
public static class ZausFormatter {
/// <summary>
/// Turn a token into a token-mask
/// </summary>
/// <param name="token">the token</param>
/// <returns></returns>
private static string Tokenize(object token) {
return string.Format("{{{0}}}", token);
}
/// <summary>
/// Given a duplicating list of tokens, repeat and effect named replacements
/// </summary>
/// <param name="mask">the named token list</param>
/// <param name="tokens">the list of tokens, given as (key, value) subsequent pairs. Expects the "key" to be a string.</param>
/// <returns></returns>
public static string ZausFormat(this string mask, params object[] tokens) {
var result = new StringBuilder(mask);
for (int i = tokens.Length - 1; i > 0; i -= 2) {
result.Replace(Tokenize(tokens[i - 1]), tokens[i].ToString());
}
return result.ToString();
}
#region ------------------ fancy-shmancy anonymous object source --------------------------
/// <summary>
/// Turn an anonymous object into a Dictionary; internally similar to <see cref="System.Web.Mvc.HtmlHelper.AnonymousObjectToHtmlAttributes"/>
/// </summary>
/// <remarks>http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/5ac8586b78b3#src%2fSystem.Web.Mvc%2fHtmlHelper.cs</remarks>
/// <param name="collection">the anonymous collection of property-values</param>
/// <returns>A typecast dictionary from the object</returns>
private static IDictionary<string, Tvalue> AnonymousObjectToDictionary<Tvalue>(object collection) {
var result = new Dictionary<string, Tvalue>();
if (collection != null) {
foreach (System.ComponentModel.PropertyDescriptor property in System.ComponentModel.TypeDescriptor.GetProperties(collection)) {
result.Add(property.Name,/* (typeof(Tvalue).IsValueType ? */(Tvalue)(property.GetValue(collection)));
}
}
return result;
}
/// <summary>
/// Given a duplicating list of tokens, repeat and effect named replacements
/// </summary>
/// <param name="mask">the named token list</param>
/// <param name="tokens">the list of tokens, given as (key, value) subsequent pairs. Expects the "key" to be a string.</param>
/// <returns></returns>
public static string ZausFormatObject(this string mask, object tokenList) {
var tokens = AnonymousObjectToDictionary<object>(tokenList);
var result = new StringBuilder(mask);
foreach (var token in tokens) {
result.Replace(Tokenize(token.Key), token.Value.ToString());
}
return result.ToString();
}
#endregion ------------------ fancy-shmancy anonymous object source --------------------------
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment