将对象格式化为主体和主体的通用方法?

时间:2014-05-19 16:09:56

标签: c# casting strong-typing

我正在尝试获取对象列表并将其格式化为电子邮件主题和正文。为了说明我在做什么,请使用以下示例

public string GetSubject(Person myPerson) 
{ 
    return String.Format("To {0}", myPerson.Name); 
}

public string GetMessage(Person myPerson) 
{ 
    return String.Format("Dear {0}, Your new salary: {1}", 
        myPerson.Name, myPerson.Salary); 
}

public string GetSubject(VacationDay dayOff) 
{ 
    return String.Format("Vacation reminder!"); 
}

public string GetMessage(VacationDay dayOff) 
{ 
    return String.Format("Reminder: this {0} is a vacation day!", dayOff.Name); 
}

后来我收到了一堆我想要批量发送的电子邮件:

// myEmailObjects is a "List<object>"
foreach (var emailItem in myEmailObjects)
{
    SendEmail(from, to, GetSubject(emailItem), GetMessage(emailItem));
}

问题是此代码无法编译,因为编译器无法解析调用哪个GetSubjectGetMessage例程。有没有通用的方法来编写它而不使用isas运算符来检查类型?

2 个答案:

答案 0 :(得分:7)

这就是 interfaces 的用途。从概念上讲,接口就像一个合同,类可以在必须定义接口指定的方法的地方签名。将每个GetSubject()GetMessage()方法定义为相应类的成员方法,然后创建以下接口:

public interface IEmailable {
    string GetSubject();
    string GetMessage();
}

然后,让所有涉及的类实现接口:

public class VacationDay : IEmailable

您现在可以创建List<IEmailable>(),并且可以在其元素上调用这两种方法。

答案 1 :(得分:1)

假设保留List<object>,最简单的做法是检查迭代器变量的类型,然后选择要执行的操作。

foreach (var emailItem in myEmailObjects)
{
    if (emailItem is Person)
    {
        SendEmail(from, to, GetSubject((Person)emailItem), 
            GetMessage((Person)emailItem));
    }
    else if (emailItem is VacationDay)
    {
        SendEmail(from, to, GetSubject((VacationDay)emailItem), 
            GetMessage((VacationDay)emailItem));
    }

}

其他选项包括创建一个界面(如另一个答案中所述,但如果你有一个对象列表这将很难),并制作扩展方法(也很难用一个对象列表)。