在C#中发送电子邮件的LINQ返回类型问题

本文关键字:LINQ 返回类型 问题 电子邮件 | 更新日期: 2023-09-27 18:28:27

我是一名较新的开发人员,正在努力更好地掌握LINQ。我正试图从MailingAddresses的web.config中获取一个字符串,并将该字符串拆分为";"或","字符,然后将这些地址中的每个地址添加到邮件地址集合中,但我遇到了几个问题。

相关代码

    var emailTo = ConfigurationManager.AppSettings["eROCSendTo"];
    IEnumerable<MailAddress> mailAddresses = emailTo.Select(x => x.ToString().Split(new string[] {";", ","}, StringSplitOptions.RemoveEmptyEntries)).Select(y => new MailAddress(y.ToString().Trim()));
    mail.To.Add(mailAddresses);

我注意到,如果我尝试将mailAddresses初始化为MailMessage.To属性,则签名需要一个字符串或MailAddress项。我是完全错了,还是离编译代码很近了?

我希望通过LINQ学习一些新东西,同时避免代码中的一堆foreach循环。如果有帮助的话,这是目前的完整方法。

SendMail方法

public static void SendMail(String Message)
    {
        using (var mail = new MailMessage())
        {
            var emailTo = ConfigurationManager.AppSettings["eROCSendTo"];
            IEnumerable<MailAddress> mailAddresses = emailTo.Select(x => x.ToString().Split(new string[] {";", ","}, StringSplitOptions.RemoveEmptyEntries)).Select(y => new MailAddress(y.ToString().Trim()));
            mail.To.Add(mailAddresses);
            mail.From = new MailAddress("info@test.com");
            mail.Body = Message;
            mail.IsBodyHtml = false;
            mail.Subject = "New Contact Form Submitted";
            using (var smtp = new SmtpClient())
            {
                smtp.Send(mail);
            }
        }
    }

请随意批评我的代码中的任何其他内容,因为我的主要目标是变得更好,符合社区的"最佳标准"。

在C#中发送电子邮件的LINQ返回类型问题

mail.To.Add需要一个地址,因为To实现Collection<MailAddress>并使用Collection.Add方法。然后要添加所有地址,只需枚举它并将每个地址添加到集合中:

foreach(var address in mailAddresses)
{
    mail.To.Add(address);
}

对于明确的LINQ解决方案,您可以使用下一个代码:

emailTo.Select(x => x.ToString().Split(new string[] {";", ","}, StringSplitOptions.RemoveEmptyEntries)).Select(y => new MailAddress(y.ToString().Trim())).ToList().ForEach(mail.To.Add);

但是它将导致在方法CCD_ 7中为新的CCD_。为了避免这种情况,您可以在foreach循环中添加LINQ查询(但现在您的代码可读性较差):

foreach(var address in emailTo.Select(x => x.ToString().Split(new string[] {";", ","}, StringSplitOptions.RemoveEmptyEntries)).Select(y => new MailAddress(y.ToString().Trim()))) 
{ 
    mail.To.Add(address); 
}

我想您可能没有注意到emailTo是一个字符串变量

        string emailTo = ConfigurationManager.AppSettings["eROCSendTo"];

因此emailTo.Select(x => ...)将遍历字符串-的每个字符(并对该字符调用"ToString().Splitt()"等)。

当该方法允许您传递具有多个电子邮件地址的字符串(以,分隔)时,您不需要将其全部拆分:

abc@example.com,asd@example.com

请阅读此处。

您可以将所有;替换为,:

var emailTo = ConfigurationManager.AppSettings["eROCSendTo"].Replace(';', ',');

由于To.Add只接受MailAddress而不是集合,因此您可以将linq查询更改为迭代,并在查询本身中添加项目

emailTo.Select(x => x.ToString().Split(new string[] {";", ","}, StringSplitOptions.RemoveEmptyEntries)).Select(y => new MailAddress(y.ToString().Trim())).ToList().ForEach(t =>  mail.To.Add(t));

或者,您可以为AddRange编写MailAddressCollection的扩展,如下所示

public static class CollectionExtensions
{
    public static void AddRange<T>(this ICollection<T> target, IEnumerable<T> items)
    {
        foreach(var item in items)
        {
            target.Add(item);
        }   
    }
}

现在将其用作

mail.To.AddRange(mailAddresses);