UPDIf the whole question is how to generode the name of the file's log, why don't you just do that? In configuration, we'll have a validation from the z.NET format for the date:{
"logFilePattern" : "yyyy.MM.dd.log"
}
Then in the code we'll bite it and get the file name:const string extension = ".log";
var datePattern = logFilePattern.Remove(logFilePattern.IndexOf(extension), extension.Length);
DateTime date = DateTime.UtcNow;
var logFileName = date.ToString(datePattern) + extension;
About the challenge in generalThe naive application may be simply a substitute for:string stringPattern = "Name = {name}";
string name = "Fred";
string formatted = stringPattern.Replace($"{{nameof(name)}}", name);
There are two shortcomings:non-universal code (with a separate method, type) FormatString(pattern, value1, value2, ...))not taking into account the possible escaping of the figure brackets (line) "{{name}}" is not a chablon, but the replacement will be made)If there are several values, we will be fertilizing extra lines.Method of species FormatString(pattern, value1, value2, ...)I understand that it is unrealistic because there is no way in the method called to know the names of the parameters with which it was called. Therefore, a dictionary, for example:public static string FormatString(string pattern, IDictionary<string, object> values)
Escaping can be processed with regular expressions, but given that parameters may be somewhat, it may also be an overly heavy operation. Implementation is therefore largely dependent on the desired degree of optimization, ideally handicap. char[]/List<char> and change it.Tonight, looked like:public static string FormatString(string pattern, IDictionary<string, object> values)
{
var buffer = pattern.ToList();
int replaceStartIndex = -1;
int replaceEndIndex = -1;
int index = 0;
while (index < buffer.Count)
{
var character = buffer[index];
if (character == '{')
{
if (replaceStartIndex == -1)
{
replaceStartIndex = index;
}
else
{
replaceStartIndex = -1;
}
}
else if (character == '}')
{
if (replaceEndIndex == -1)
{
replaceEndIndex = index;
}
else
{
replaceEndIndex = -1;
}
}
if (replaceStartIndex > -1 && replaceEndIndex > -1)
{
var key = new string(buffer.Skip(replaceStartIndex + 1).Take(replaceEndIndex - replaceStartIndex - 1).ToArray());
var value = values[key];
var stringValue = value?.ToString();
buffer.RemoveRange(replaceStartIndex, replaceEndIndex - replaceStartIndex + 1);
if (stringValue != null)
{
buffer.InsertRange(replaceStartIndex, stringValue.ToCharArray());
index = replaceStartIndex + stringValue.Length;
}
else
{
index = replaceStartIndex;
}
replaceStartIndex = -1;
replaceEndIndex = -1;
}
else
{
index++;
}
}
return string.Join("", buffer);
}
Verification:static void Main(string[] args)
{
string stringPattern = "Name = {name}, Age = {age}, Null = {nullString}, Escape = {{escape}}";
string name = "Fred";
int age = 42;
string nullString = null;
string escape = "You shouldn't see this";
var values = new Dictionary<string, object>()
{
[nameof(name)] = name,
[nameof(age)] = age,
[nameof(nullString)] = nullString,
[nameof(escape)] = escape
};
string formatted = FormatString(stringPattern, values);
Console.WriteLine(formatted);
}
Conclusion:Name = Fred, Age = 42, Null = , Escape = {escape}