我有一组用于我的应用发送的电子邮件的模板。模板中嵌入了与业务对象属性相对应的代码。
是否有一种比调用
更优雅的方式string.Replace("{!MyProperty!}", item.MyProperty.ToString())
几百万次?也许是XMLTransform,正则表达式或其他一些魔术?我正在使用C#3.5。
答案 0 :(得分:3)
首先,当我这样做时,我使用StringBuilder.Replace(),因为我发现在使用3个或更多替换时它的性能更适合。
当然还有其他方法可以做到这一点,但我发现尝试其他项目通常不值得付出额外的努力。
您可以使用反射我想自动更换,这可能是唯一“更好”的方式。
答案 1 :(得分:2)
public static string Translate(string pattern, object context)
{
return Regex.Replace(pattern, @"\{!(\w+)!}", match => {
string tag = match.Groups[1].Value;
if (context != null)
{
PropertyInfo prop = context.GetType().GetProperty(tag);
if (prop != null)
{
object value = prop.GetValue(context);
if (value != null)
{
return value.ToString();
}
}
}
return "";
});
}
Translate("Hello {!User!}. Welcome to {!GroupName!}!", new {
User = "John",
GroupName = "The Community"
}); // -> "Hello John. Welcome to The Community!"
答案 2 :(得分:1)
您可以使用正则表达式执行此操作,但您的正则表达式替换也会因每个属性而异。我会坚持使用string.Replace
。
使用反射检索属性并将其替换为循环:
foreach (string property in properties)
{
string.Replace("{!"+property+"!}",ReflectionHelper.GetStringValue(item,property));
}
只需实施ReflectionHelper.GetStringValue
方法并使用反射来检索商品对象类型的所有属性。
答案 3 :(得分:1)
内置WebControl,System.Web.UI.WebControls.MailDefinition执行string replacements(以及其他内容)。遗憾的是,他们将它紧密地耦合到app.config中的Smtp设置和一个Web控件,然后将其密封以保护继承者。
但是,它确实处理了你在邮件模板引擎中最想要的一些东西 - 来自文件,html电子邮件,嵌入对象等的正文文本.Reflector显示实际的替换是用foreach循环和Regex处理的.Replace - 这对我来说似乎也是一个合理的选择。
快速浏览一下就会发现,如果您可以使用app.config中的起始地址(之后可以在返回的MailMessage上更改它),则只需要嵌入资源的所有者控件或BodyFileName。
如果你正在使用ASP.NET或者可以忍受这些限制 - 我会选择MailDefinition。否则,只需要在字典和Regex.Replace上做一个foreach。由于身体的反复分配,这是一个有点记忆力的东西 - 但它们是短暂的,不应该造成很大的问题。
var replacements = new Dictionary<string, object>() {
{ "Property1", obj.Property1 },
{ "Property2", obj.Property2 },
{ "Property3", obj.Property3 },
{ "Property4", obj.Property4 },
}
foreach (KeyValuePair<string, object> kvp in replacement) {
body = Regex.Replace(body, kvp.Key, kvp.Value.ToString());
}
如果您确实拥有很多属性,请先使用Regex.Match读取您的身体,然后反映到这些属性。
答案 4 :(得分:0)
看完前面包括的示例后,我想我会看一下真正的代码。 @ mark-brackett你比你知道的要近。
declare @a GEOMETRY = Geometry::STGeomFromText('LINESTRING (-83 24, -80.4907132243685 24.788632986627039)', 4326)
declare @b GEOMETRY = Geometry::STGeomFromText('LINESTRING (-74.7 21.8, -75.7 22.1, -77.8 22.6, -79.4 23.3, -80.4 24.5, -81.5 28, -84 33, -87 36)', 4326)
DECLARE @intersectionPoint geometry = @a.STIntersection(@b) -- POINT (-80.49071322436852 24.788632986627078)
IF @intersectionPoint IS NULL
THROW 50000, '@intersectionPoint not found', 1
-- Expect 1, Result 0
SELECT @b.STIntersects(@intersectionPoint)