編集: LoveMeSomeCode からの回答に基づいて、この問題は VB.Net でのみ発生すると思います。
変更されたプロパティの古い値を辞書に保存し、元に戻す必要があるときにリフレクションを介して設定することにより、クラスを以前の状態に戻そうとしています。古い値が Nothing (null) の場合、プロパティを設定しようとすると null 参照例外が発生するという問題があります。これが私が試したことです。
次のような for each ループを想定します。
For Each pair As KeyValuePair(Of String, Object) In myOldValues
...
Next
方法 1:
CallByName(Me, pair.Key, CallType.Set, pair.Value)
方法 2:
Me.GetType().InvokeMember(pair.Key, Reflection.BindingFlags.SetProperty, Nothing, Me, pair.Value)
方法 3:
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 参照例外が発生します。セッターは null 値を保持できます (多くの場合、プロパティは文字列です)。何が間違っているのか、どうすれば回避できますか?
編集: null を直接渡すと、各メソッドは失敗します。
編集:誰かに役立つ場合のスタックトレースは次のとおりです。
方法 1 System.NullReferenceException: オブジェクト参照がオブジェクトのインスタンスに設定されていません。Microsoft.VisualBasic.CompilerServices.Symbols.Container.InvokeMethod (メソッド TargetProcedure、オブジェクト [] 引数、ブール値 [] CopyBack、BindingFlags フラグ) で Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateSet (オブジェクト インスタンス、型の種類、文字列 MemberName、オブジェクト[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean OptimisticSet, Boolean RValueBase, CallType CallType) Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(Object Instance, String MethodName, CallType UseCallType, Object[] Arguments) at myProject myfileの .Presenter.CustomerDetailPresenter.RevertCustomer() : 378 行目
方法 2 System.Reflection.TargetInvocationException: 呼び出しのターゲットによって例外がスローされました。---> System.NullReferenceException: オブジェクト参照がオブジェクトのインスタンスに設定されていません。私のプロジェクトで.Presenter.CustomerDetailPresenter.set_City(String value) --- 内部例外スタック トレースの終了 --- System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.RuntimeMethodHandle .InvokeMethodFast (オブジェクト ターゲット、オブジェクト [] 引数、シグネチャ sig、MethodAttributes methodAttributes、RuntimeTypeHandle typeOwner) で System.Reflection.RuntimeMethodInfo.Invoke(オブジェクト obj、BindingFlags invokeAttr、バインダー バインダー、オブジェクト [] パラメーター、CultureInfo カルチャ、ブール値の skipVisibilityChecks) でSystem.Reflection.RuntimeMethodInfo.Invoke(オブジェクト obj、BindingFlags invokeAttr、バインダー バインダー、Object[] パラメーター、CultureInfo カルチャ) System.RuntimeType.InvokeMember(文字列名、BindingFlags bindingFlags、バインダー バインダー、System.Type.InvokeMember(文字列名、BindingFlags invokeAttr、バインダー バインダー、オブジェクト ターゲット、Object[] args)myProject .Presenter.CustomerDetailPresenter.RevertCustomer()
方法 3 System.Reflection.TargetInvocationException: 呼び出しのターゲットによって例外がスローされました。---> System.NullReferenceException: オブジェクト参照がオブジェクトのインスタンスに設定されていません。私のプロジェクトで.Presenter.CustomerDetailPresenter.set_City(String value) --- 内部例外スタック トレースの終了 --- System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.RuntimeMethodHandle System.Reflection.RuntimeMethodInfo.Invoke(Object obj、BindingFlags invokeAttr、Binder バインダー、Object[] パラメーター、CultureInfo カルチャ、ブール値の skipVisibilityChecks) での .InvokeMethodFast(Object ターゲット、Object[] 引数、シグネチャ sig、MethodAttributes methodAttributes、RuntimeTypeHandle typeOwner)
System.Reflection.RuntimeMethodInfo.Invoke (オブジェクト obj、BindingFlags invokeAttr、バインダー バインダー、Object [] パラメーター、CultureInfo カルチャ) で System.RuntimeType.InvokeMember (文字列名、BindingFlags bindingFlags、バインダー バインダー、オブジェクト ターゲット、Object [] providedArgs、 ParameterModifier[] 修飾子、CultureInfo カルチャ、String[] namedParams) の System.Type.InvokeMember(String 名、BindingFlags invokeAttr、Binder バインダー、オブジェクト ターゲット、Object[] args) at myProject .Presenter.CustomerDetailPresenter.RevertCustomer()