MailMesage F#扩展类型,用于序列化为MIME字符串

时间:2018-01-29 06:49:09

标签: f# mailmessage rfc822

我试图让.NET中的MailMessage返回MIME消息的字符串,但是在交付的类中没有提供。还有一个很好的answer关于如何创建一个C#扩展方法来修补类以提供功能。我试图通过类型扩展将其移植到F#,但我对如何提供参数感到困惑(特别是考虑到其中一个是F#关键字)。

非常感谢您解释如何正确完成答案。

这是我到目前为止所得到的(当然,这当然不会编译):

open System.Net.Mail

module MailExtension =
    type MailMessage with 
        member this.toEml mail =
            let stream = new MemoryStream();
            let mailWriterType = mail.GetType().Assembly.GetType("System.Net.Mail.MailWriter");
            let mailWriter = Activator.CreateInstance(
                                type: mailWriterType,
                                bindingAttr: BindingFlags.Instance | BindingFlags.NonPublic,
                                binder: null,
                                args: new object[] { stream },
                                culture: null,
                                activationAttributes: null)

            mail.GetType().InvokeMember(
                                name: "Send",
                                invokeAttr: BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
                                binder: null,
                                target: mail,
                                args: new object[] { mailWriter, true, true });


            Encoding.UTF8.GetString(stream.ToArray());

1 个答案:

答案 0 :(得分:3)

以下是关于如何将C#翻译为F#的一些提示:

  • ;不再需要
  • 对IDisposables使用“use”而不是“let”
  • 对于数组使用[| member1,member2 |]
  • 用于命名参数使用name = value
  • 在``name``
  • 中的名字中包装关键字
  • 按位运算符是|||和&&&
  • 使用实例名称而不是参数

编译的代码:

open System
open System.IO
open System.Net.Mail
open System.Reflection
open System.Text

module MailExtension =
    type MailMessage with 
        member this.toEml () =
            use stream = new MemoryStream()
            let mailWriterType = this.GetType().Assembly.GetType("System.Net.Mail.MailWriter")
            let mailWriter = Activator.CreateInstance(
                                ``type`` = mailWriterType,
                                bindingAttr = (BindingFlags.Instance ||| BindingFlags.NonPublic),
                                binder = null,
                                args = [| stream |],
                                culture = null,
                                activationAttributes = null)

            this.GetType().InvokeMember(
                                name = "Send",
                                invokeAttr = (BindingFlags.Instance ||| BindingFlags.NonPublic ||| BindingFlags.InvokeMethod),
                                binder = null,
                                target = this,
                                args = [| mailWriter, true, true |])


            Encoding.UTF8.GetString(stream.ToArray())

然后使用:

open MailExtension
let m = new MailMessage()
m.toEml () |> ignore