【发布时间】:2010-10-03 01:12:24
【问题描述】:
编辑:根据 LoveMeSomeCode 的回答,我相信这个问题只出现在 VB.Net 中。
我试图通过将更改的属性的旧值保存在字典中并在需要恢复时通过反射设置它们来将类恢复到以前的状态。我遇到了一个问题,如果旧值是 Nothing (null),我在尝试设置属性时会得到一个空引用异常。这是我尝试过的。
为每个循环假设一个这样的:
For Each pair As KeyValuePair(Of String, Object) In myOldValues
...
Next
方法一:
CallByName(Me, pair.Key, CallType.Set, pair.Value)
方法二:
Me.GetType().InvokeMember(pair.Key, Reflection.BindingFlags.SetProperty, Nothing, Me, pair.Value)
方法三:
Dim propInfo As System.Reflection.PropertyInfo = Me.GetType.GetProperty(pair.Key)
propInfo.SetValue(Me, Convert.ChangeType(pair.Value, propInfo.PropertyType), Nothing)
对于这些方法中的每一个,当 pair.Value 为 null 时,我都会得到一个 null 引用异常。 setter 能够保存一个空值(通常该属性是一个字符串)。我做错了什么或如何解决?
编辑:如果我也直接传递 null,每个方法都会失败。
编辑:如果对任何人有帮助,以下是堆栈跟踪:
方法一 System.NullReferenceException:对象引用未设置为对象的实例。 在 Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod(方法 TargetProcedure,Object[] 参数,Boolean[] CopyBack,BindingFlags 标志) 在 Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateSet(对象实例,类型类型,字符串成员名称,对象 [] 参数,字符串 [] 参数名称,类型 [] 类型参数,布尔 OptimisticSet,布尔 RValueBase,CallType CallType) 在 Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(对象实例,字符串方法名,CallType UseCallType,对象 [] 参数) myProject.Presenter.CustomerDetailPresenter.RevertCustomer() in myfile:第 378 行
方法二 System.Reflection.TargetInvocationException:调用的目标已引发异常。 ---> System.NullReferenceException:对象引用未设置为对象的实例。 在 myProject.Presenter.CustomerDetailPresenter.set_City(字符串值) --- 内部异常堆栈跟踪结束 --- 在 System.RuntimeMethodHandle._InvokeMethodFast(对象目标,Object[] 参数,SignatureStruct& sig,MethodAttributes methodAttributes,RuntimeTypeHandle typeOwner) 在 System.RuntimeMethodHandle.InvokeMethodFast(对象目标,对象 [] 参数,签名 sig,MethodAttributes 方法属性,RuntimeTypeHandle typeOwner) 在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr,Binder binder,Object[] 参数,CultureInfo 文化,布尔型 skipVisibilityChecks) 在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr,Binder binder,Object[] 参数,CultureInfo 文化) 在 System.RuntimeType.InvokeMember(字符串名称、BindingFlags bindingFlags、Binder binder、Object 目标、Object[] providedArgs、ParameterModifier[] 修饰符、CultureInfo 文化、String[] namedParams) 在 System.Type.InvokeMember(字符串名称,BindingFlags invokeAttr,Binder binder,Object target,Object[] args) 在 myProject.Presenter.CustomerDetailPresenter.RevertCustomer()
方法三 System.Reflection.TargetInvocationException:调用的目标已引发异常。 ---> System.NullReferenceException:对象引用未设置为对象的实例。 在 myProject.Presenter.CustomerDetailPresenter.set_City(字符串值) --- 内部异常堆栈跟踪结束 --- 在 System.RuntimeMethodHandle._InvokeMethodFast(对象目标,Object[] 参数,SignatureStruct& sig,MethodAttributes methodAttributes,RuntimeTypeHandle typeOwner) 在 System.RuntimeMethodHandle.InvokeMethodFast(对象目标,对象 [] 参数,签名 sig,MethodAttributes 方法属性,RuntimeTypeHandle typeOwner) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfoculture, Boolean skipVisibilityChecks)
在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] 参数, CultureInfo 文化) 在 System.RuntimeType.InvokeMember(字符串名称、BindingFlags bindingFlags、Binder binder、Object 目标、Object[] providedArgs、ParameterModifier[] 修饰符、CultureInfo 文化、String[] namedParams) 在 System.Type.InvokeMember(字符串名称,BindingFlags invokeAttr,Binder binder,Object target,Object[] args) 在 myProject.Presenter.CustomerDetailPresenter.RevertCustomer()
【问题讨论】:
-
你确定 PropertyInfo.SetValue 是抛出异常的方法吗?
-
那个或者它的子方法之一,就是那一行。
-
检查异常堆栈跟踪;您应该能够辨别哪个方法引发了异常。如果您无法弄清楚,请尝试单独调用 Convert.ChangeType。我怀疑该方法正在引发异常。
-
感谢您帮助我解决这个问题。我曾尝试将 Convert.ChangeType 和所有其他子调用分开。在我调用实际尝试调用 setter 的任何函数之前,它们都正常工作。
标签: .net vb.net reflection null