Skip to content

Instantly share code, notes, and snippets.

@tcartwright
Last active December 1, 2023 15:25
Show Gist options
  • Save tcartwright/cca1247a741eaf9f191003fe3d599edd to your computer and use it in GitHub Desktop.
Save tcartwright/cca1247a741eaf9f191003fe3d599edd to your computer and use it in GitHub Desktop.
C#: Run time interprolation
public class NamedParameter
{
public string Name { get; set; } = null!;
public object Value { get; set; }
public NamedParameter(string name, object value)
{
if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentNullException(nameof(name)); }
if (value == null) { throw new ArgumentNullException(nameof(value)); }
Name = name;
Value = value;
}
}
public static partial class Extensions
{
public static string ToFormattedString(this string value, params NamedParameter[] parameters)
{
var paramsArray = parameters
.Select(p => Expression.Parameter(p.Value!.GetType(), p.Name))
.ToArray();
var paramValues = parameters
.Select(p => p.Value)
.ToArray();
return Regex.Replace(value, @"(?<!{){(?!{)(?<exp>[^}]+)(?<!})}(?!})", match => {
var exp = DynamicExpressionParser
.ParseLambda(paramsArray, null, match.Groups["exp"].Value);
return (exp.Compile().DynamicInvoke(paramValues) ?? "").ToString()!;
});
}
}
@tcartwright
Copy link
Author

tcartwright commented Dec 1, 2023

This function provides run time interpolation so that you can store strings in database tables or config files, and still use run time interpolation.

Issue: You can use {{ or }} to signify a literal bracket. However, you cannot do so inside of a bracket that you wish to replace. EX:

var name = "World";
ToFormattedString("Hello, {name}!", new NamedParameter("name", name)) //this works
ToFormattedString("Hello, { "{{" + name + "}}" }!", new NamedParameter("name", name)) //this does not work

More infor on interpolation: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment