The basic idea is to replace all special expressions, e.g., [%InvoiceNo%]
, [%DueDate%]
, in a string with the properties of an object, Invoice invoice
.
string str = "Your invoice [%InvoiceNo%] will be due on [%DueDate%]";
Invoice invoice = new Invoice { InvoiceNo = "123456", DueDate = DateTime.Parse("2011.12.29") };
string result = GetNewValue(str, invoice);
//The expected result is: Your invoice 123456 will be due on 11/29/2011
I think the simplest way to implement GetNewValue()
could be
private string GetNewValue(string str, Invoice invoice)
{
str = str.Replace("[%InvoiceNo%]", invoice.InvoiceNo);
str = str.Replace("[%DueDate%]", invoice.DueDate.ToString());
return str;
}
However, in my case, Invoice
has a hundred properties and the target string only contains one or two properties. I rewrite GetNewValue()
in the way I think it should work more efficiently. Here is my code
private string GetNewValue(string str, Invoice invoice)
{
List<string> expressions = new List<string>();
List<string> fields = new List<string>();
var startIndices = str.IndicesOf("[%");
var endIndices = str.IndicesOf("%]");
int startLen = "[%".Length;
int endLen = "%]".Length;
for (int i = 0; i < startIndices.Count; i++)
{
expressions.Add(str.Substring(startIndices[i],
endIndices[i] - startIndices[i] + endLen));
fields.Add(str.Substring(startIndices[i] + startLen,
endIndices[i] - startIndices[i] - startLen));
}
for (int i = 0; i < expressions.Count; i++)
str = str.Replace(expressions[i], invoice.GetValueByName(fields[i]).ToString());
return str;
}
StringExtender IndicesOf()
public static List<int> IndicesOf(this string target, string search)
{
List<int> indices = new List<int>();
int startIndex = 0;
int index;
while ((index = target.IndexOf(search, startIndex)) > -1)
{
indices.Add(index);
startIndex = index + 1;
}
return indices;
}
GetValueByName()
using Reflection
public class Invoice
{
// Properties
......
public object GetValueByName(string name)
{
PropertyInfo myProperty = typeof(Invoice).GetProperty(name);
return myProperty.GetValue(this, null);
}
}
How can I improve this code? Fast, less memory usage, or one-liner
Don't tell me the first approach is better. Orz
Thanks :)