Согласно документации MSDN , MailFormat теперь устарел. Предупреждение должно выглядеть так:
Предупреждение
Этот API теперь устарел. Рекомендуемая альтернатива: System.Net.Mail.
blockquote>Я бы предложил использовать свойство
MailMessage.AlternateViews
, чтобы предоставить HTML и текстовую альтернативу дляMailMessage
.Подробнее о MailMessage.AlternateViews . Согласно документации AlternateViews:
Используйте свойство AlternateViews, чтобы указать копии сообщения электронной почты в разных форматах. Например, если вы отправляете сообщение в формате HTML, вам также может потребоваться предоставить текстовую версию на случай, если некоторые из получателей используют программы чтения электронной почты, которые не могут отображать содержимое HTML. Пример, демонстрирующий создание сообщения с альтернативными представлениями, см. В AlternateViews.
blockquote>Ваш измененный код выглядит следующим образом:
public static string SendMail(string strsender, string strReceiver, string strsubject, string strbody) { try { MailMessage vMailMessage = new MailMessage(); char[] separator = { ',' }; vMailMessage.From = GetEmailAddress(strsender.Trim(), separator); //寄件人 //存取被拒 vMailMessage.To.Add(GetEmailAddress(strReceiver.Trim(), separator)); //收件人 //vMailMessage.Cc = GetEmailAddress(vDataRow["CC"].ToString().Trim(), separator); //副本 //vMailMessage.Bcc = GetEmailAddress(vDataRow["BCC"].ToString().Trim(), separator); //密件副本 vMailMessage.Subject = strsubject.Trim(); //主旨 vMailMessage.IsBodyHtml = true; vMailMessage.Body = strbody; SmtpMail.SmtpServer = "Webmail"; //設定Mail伺服器 SmtpMail.Send(vMailMessage); //發送mail return "ok"; } catch (Exception ex) { throw new Exception(ex.Message); } }
Вы всегда можете определить свою собственную trace
функцию:
def trace[T](x: T) = {
println(x) // or your favourite logging framework :)
x
}
Тогда для понимания будет выглядеть:
for {
outer <- ll
inner <- trace(outer)
} yield inner
В качестве альтернативы, если вы хотите печатать больше информации, вы можно определить trace
следующим образом:
def trace[T](message: String, x: T) = {
println(message)
x
}
и для понимания будет выглядеть:
for {
outer <- ll
inner <- trace("Value: " + outer, outer)
} yield inner
РЕДАКТИРОВАТЬ: В ответ на ваш комментарий, да, Вы можете написать trace
так, чтобы он действовал справа от цели! Вы просто должны использовать немного неявного обмана. И на самом деле, это выглядит намного лучше, чем применительно к левой стороне :).
Чтобы сделать это, вы должны сначала определить класс Traceable
, а затем определить неявное преобразование в этот класс:
class Traceable[A](x: A) {
def traced = {
println(x)
x
}
}
implicit def any2Traceable[A](x: A) = new Traceable(x)
Тогда единственное, что вам нужно изменить в коде, который вы предоставил это добавить traced
в конец значения, которое вы хотите отслеживать. Например:
for {
outer <- ll
inner <- outer traced
} yield inner
(это переводится компилятором Scala в outer.traced
)
Для чего бы это ни стоило, поскольку задание является фиктивным, вы можете заменить a
на _
:
for {
outer <- ll // ; // semi-colon needed on Scala 2.7
_ = Console.println(outer) // dummy assignment makes it compile
inner <- outer
} yield inner
Начиная с Scala 2.13
, операция связывания tap
была включена в стандартную библиотеку и может использоваться с минимальной навязчивостью везде, где нам нужно напечатать некоторое промежуточное состояние конвейера: ]
import util.chaining._
// val lists = List(List(1, 2), List(1))
for {
outer <- lists
inner <- outer.tap(println)
} yield inner
// List(2, 4, 6)
// List(4, 8, 12)
// ls: List[Int] = List(4, 8, 12)
Операция сцепления tap
применяет побочный эффект (в данном случае println
) к значению (в данном случае список outer
) при возврате нетронутое значение:
def tap [U] (f: (A) => U): A
Ответ Флавиу вдохновил меня попробовать сыграть с имплицитами. Идея состоит в том, чтобы увидеть, выглядит ли трассировка лучше с «трассировкой», расположенной дальше вправо по строке:
import Trace._
object Main {
def main(args:Array[String]) {
val listList = List(List(1,2,3), List(3,4))
for {
list <- trace1(listList, "lList is: %s", listList) // trace()
item <- list traced("list is: %s", list) // implicit
} yield item
Я также хотел попробовать смешать запись ошибок в том же понимании. Ведение журнала ошибок выглядит лучше всего в сочетании с подходом Дэниела:
val optOpt:Option[Option[Int]] = Some(Some(1))
for {
opt <- optOpt;
_ = trace2("opt found: %s", opt) // trying Daniel's suggestion
int <- opt orElse
err("num not found in: %s", opt) // together with error logging
} yield int
}
}
Вот вспомогательный код для обоих экспериментов:
object Trace {
def trace1[T](any:T, message:String, params:AnyRef*):T = {
Console println String.format("TRA: " + message, params:_*)
any
}
def trace2[T](message:String, params:AnyRef*) {
Console println String.format("TRA: " + message, params:_*)
}
def err[T](message:String, params:AnyRef*):Option[T] = {
Console println String.format("ERR: " + message, params:_*)
None
}
implicit def anyRefToTraceable[T](anyRef:T):Traceable[T] = {
new Traceable(anyRef)
}
class Traceable[T](val self:T) {
def traced(message:String, params:AnyRef*):T = {
Console println String.format("TRA: " + message, params:_*)
self
}
}
}