使用Activator.CreateInstance反射创建MailMessage时提示变量为空
反射创建MailMessage时出现ArgumentNullException的原因分析
我尝试通过反射使用System.Net.Mail相关功能,编写代码如下:
string to = "user@example.com"; string from = "user@example.com"; string title = "Test"; string body = "Test Email"; Type t1 = Type.GetType("System.Net.Mail.MailMessage"); Object test = Activator.CreateInstance(t1, new object[] { to, from, title, body });但运行编译时提示to、from、title和body均为空(System.ArgumentNullException: Value cannot be null.),请问这是什么原因?
嘿,这个问题我之前也踩过坑!其实错误提示有点误导人——你的to、from这些变量根本不是空的,真正的问题出在Type.GetType("System.Net.Mail.MailMessage")这一行。
当你只传入类的全名而不带程序集信息时,Type.GetType很可能找不到对应的类型,直接返回了null。这时候你拿着null去调用Activator.CreateInstance,内部的参数校验逻辑就会混乱,抛出的错误信息看起来像是你的变量为空,但本质是你要创建实例的类型本身就没找到。
为什么会找不到类型?因为System.Net.Mail.MailMessage所在的程序集,在不同.NET版本里不一样:
- .NET Framework中它在
System.dll里 - .NET Core/.NET 5+中它在
System.Net.Mail.dll里
如果Type.GetType无法从当前加载的程序集中定位到它,就会返回null。
解决方法
你需要在类型名后面加上完整的程序集标识,让Type.GetType能精准找到它:
针对.NET Framework:
Type t1 = Type.GetType("System.Net.Mail.MailMessage, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
针对.NET Core/.NET 5+:
Type t1 = Type.GetType("System.Net.Mail.MailMessage, System.Net.Mail");
另外,你也可以先手动加载对应的程序集,再获取类型,这样更稳妥:
// .NET Framework Assembly assembly = Assembly.Load("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"); // .NET Core/.NET 5+ 替换成下面这行 // Assembly assembly = Assembly.Load("System.Net.Mail"); Type t1 = assembly.GetType("System.Net.Mail.MailMessage");
这样就能正确获取到MailMessage的类型,后续调用Activator.CreateInstance时,就会正常校验你传入的参数,不会再抛出那个误导人的空引用错误了。
内容的提问来源于stack exchange,提问作者Amateurz
相关产品推荐
相关产品推荐

