将通用对象传递给c#中的方法

时间:2015-12-04 09:47:30

标签: c# generics

我知道这个问题听起来像是重复的,但我找不到任何与我要描述的内容相关的内容。

我正在尝试构建一个html电子邮件模板项目。我有一个viewmodel(为了清楚起见,只调用它们,它们只是具有该电子邮件所需属性的类,以传递需要在模板中替换的值)

 public class EmailViewModels
{
    public class AccountClosedEmailViewModel
    {
        public string Fullname { get; set; }
        public string ApplicationName { get; set; }
        public string Username { get; set; }
        public string RenewRegistrationUrl { get; set; }
    }

    public class AccountReopenedEmailViewModel
    {
        public string Fullname { get; set; }
        public string ApplicationName { get; set; }
        public string Username { get; set; }
        public string RenewRegistrationUrl { get; set; }
        public string CancelVerificationUrl { get; set; }
    }

    public class ContactFormEmailViewModel
    {
        public string Fullname { get; set; }
        public string ApplicationName { get; set; }
    }
    //rest removed for brevity
}

我想要一个采用电子邮件视图模型的方法,它可以是上面类中定义的任何一个,所以我有一个通用方法来消除我为每个视图模型类型设置BuildHtmlFromTemplate。

public string BuildHtmlFromTemplate(templateFilePath, passing any one of the email viewmodels defined in the class)
{
    var temp = File.IO.ReadAllText(templateFilePath);
    temp.Replace("{username}", modelipassedin.username);
    //do rest
    return temp;

}

这可能吗?

3 个答案:

答案 0 :(得分:3)

您可以使用像这样的反射和泛型

public string BuildHtmlFromTemplate<T>(templateFilePath, T o)
{
    var temp = File.IO.ReadAllText(templateFilePath);
    foreach(var prop in typeof(T).GetProperties()){
        temp = temp.Replace("{"+prop.Name+"}", prop.GetValue(o));
    }
    return temp;
}

或没有泛型

public string BuildHtmlFromTemplate(templateFilePath, object o)
{
    var temp = File.IO.ReadAllText(templateFilePath);
    foreach(var prop in o.GetType().GetProperties()){
        temp = temp.Replace("{"+prop.Name+"}", prop.GetValue(o));
    }
    return temp;
}

答案 1 :(得分:2)

如果您希望能够按名称访问对象属性,无论其类型如何,那么您可以:

  1. 使用反射,或

  2. 将所有课程改为词典。

  3. 要使用反射按名称获取属性的值,可以使用类似:

    的内容
    public static object GetValue(this object @this, string property)
    {
        return @this.GetType().GetProperty(property).GetValue(@this, null);
    }
    

    然后,您可以使用正则表达式来匹配和替换占位符:

    var inputHtml = @"<h1>{title}</h1> <p>{text}</p>";
    var instance = new
    {
        title = "some title",
        text = "some text"
    };
    
    // note: not much error checking here, and
    // placeholder casing is important 
    
    var regex = new Regex("{(.*?)}");
    var outputHtml = regex.Replace(inputHtml, m =>
    {
        var placeholder = m.Groups[1].Value;
    
        var prop = instance.GetType().GetProperty(placeholder);
        if (prop == null)
            return "";
    
        return prop.GetValue(instance).ToString();
    });
    

    对于第二种方法,您只需将数据存储为KeyValuePair<string, string>并进行一些简单的字符串替换。

答案 2 :(得分:-2)

public class EmailViewModel
{
  public string ToHTMLString()
  {
     //And use reflection on the properties here.
  }
}

public class AccountClosedEmailViewModel:EmailViewModel    {
    public string Fullname { get; set; }
    public string ApplicationName { get; set; }
    public string Username { get; set; }
    public string RenewRegistrationUrl { get; set; }
}

public class AccountReopenedEmailViewModel:EmailViewModel{
    public string Fullname { get; set; }
    public string ApplicationName { get; set; }
    public string Username { get; set; }
    public string RenewRegistrationUrl { get; set; }
    public string CancelVerificationUrl { get; set; }
}

public class ContactFormEmailViewModel:EmailViewModel    {
    public string Fullname { get; set; }
    public string ApplicationName { get; set; }
}

编辑: 通过这种方式,您可以移动基类中的一些常用属性,以使每个模型更轻一些。