This is not a common scenario. I am trying to invoke an exception through reflection. I have something like: testMethod is of type MethodBuilder
testMethod.GetILGenerator().ThrowException(typeof(CustomException));
My CustomException does not hav开发者_如何学编程e a default constructor, so the above statement errors out giving an ArgumentException. If there is a default constructor, this works fine.
So is there a way, this can work with no default constructor? Been trying for 2 hours now. :(
Any help is appreciated.
Thanks!
The ThrowException
method essentially boils down to the following
Emit(OpCodes.NewObj, ...);
Emit(OpCodes.Throw);
The key here is to replace the first Emit
calls with the set of IL instructions needed to create an instance of your custom exception. Then add the Emit(OpCodes.Throw)
For example
class MyException : Exception {
public MyException(int p1) {}
}
var ctor = typeof(MyException).GetConstructor(new Type[] {typeof(int)});
var gen = builder.GetILGenerator();
gen.Emit(OpCodes.Ldc_I4, 42);
gen.Emit(OpCodes.NewObj, ctor);
gen.Emit(OpCodes.Throw);
See the documentation:
// This example uses the ThrowException method, which uses the default
// constructor of the specified exception type to create the exception. If you
// want to specify your own message, you must use a different constructor;
// replace the ThrowException method call with code like that shown below,
// which creates the exception and throws it.
//
// Load the message, which is the argument for the constructor, onto the
// execution stack. Execute Newobj, with the OverflowException constructor
// that takes a string. This pops the message off the stack, and pushes the
// new exception onto the stack. The Throw instruction pops the exception off
// the stack and throws it.
//adderIL.Emit(OpCodes.Ldstr, "DoAdd does not accept values over 100.");
//adderIL.Emit(OpCodes.Newobj, _
// overflowType.GetConstructor(new Type[] { typeof(String) }));
//adderIL.Emit(OpCodes.Throw);
精彩评论