使用C#通过POP3解析Outlook邮件:读取邮件体遇CDO调用错误求助
嘿,我来帮你搞定这个报错!你遇到的An object reference is required...错误,核心原因很简单:你在静态的Main方法里直接调用了非静态的ReadMessage方法。
静态方法(比如Main)属于整个类本身,不需要创建类的实例就能运行;而非静态方法(比如你写的ReadMessage)是属于类的实例对象的,必须先创建类的实例才能调用它。这就像你不能直接用“汽车”这个类去踩油门,得先造一辆具体的汽车出来才行。
下面给你两种可行的解决方案:
方案一:把ReadMessage改成静态方法
因为你的ReadMessage方法不需要访问Program类里的任何实例字段或属性,完全可以改成静态方法,这样就能在Main里直接调用了。修改后的代码如下:
static CDO.Message ReadMessage(String emlFileName) { CDO.Message msg = new CDO.MessageClass(); ADODB.Stream stream = new ADODB.StreamClass(); stream.Open(Type.Missing, ADODB.ConnectModeEnum.adModeUnknown, ADODB.StreamOpenOptionsEnum.adOpenStreamUnspecified, String.Empty, String.Empty); stream.LoadFromFile(emlFileName); stream.Flush(); msg.DataSource.OpenObject(stream, "_Stream"); msg.DataSource.Save(); return msg; }
只需要把方法的protected修饰符改成static,其他代码不用动,就能正常调用了。
方案二:创建Program类的实例再调用方法
如果你不想修改ReadMessage的静态状态,可以在Main方法里先创建Program类的实例,再通过实例调用ReadMessage。同时建议把ReadMessage的访问修饰符从protected改成internal或public(protected是给子类访问用的,同一个类里虽然能访问,但改成internal更符合代码语义):
首先修改ReadMessage的访问修饰符:
internal CDO.Message ReadMessage(String emlFileName) { // 原有代码不变 }
然后在Main里的调用处改成:
// 创建Program类的实例 Program mailProcessor = new Program(); CDO.Message msg = mailProcessor.ReadMessage(fileName); Console.WriteLine(msg.TextBody);
额外小建议:用EAGetMail直接读取正文,省去CDO依赖
其实你已经用EAGetMail获取到了Mail对象oMail,这个库本身就提供了读取邮件正文的方法,完全不需要再转成CDO.Message来处理!比如直接写:
Console.WriteLine(oMail.TextBody); // 读取纯文本正文 // 或者读取HTML正文:Console.WriteLine(oMail.HtmlBody);
这样不仅代码更简洁,还能避免CDO库带来的版本或兼容性问题,一举两得~
内容的提问来源于stack exchange,提问作者user9813828

