This is mistake? MissingMethodException - access to a private static method with parameter 0 as parameter

I'm not sure what I should ask about it here, but here we go, and the module is testing a private static method, which has as a parameter short. I get a MissingMethodException only when this parameter is 0.

I am using VS 2010 SP1 to target Framework 4 (full), here is the minimum code to reproduce this error (we update the VB6 code, so not rough):

[DataContract] public enum NotificationResult { [EnumMember] Success, [EnumMember] StoredError, [EnumMember] InvalidId, [EnumMember] OperationError, } public sealed class NotificationContext { private static NotificationResult GetExecuteResult(short result) { NotificationResult executeResult; switch (result) { case 0: executeResult = NotificationResult.Success; break; case 1: executeResult = NotificationResult.StoredError; break; case 2: executeResult = NotificationResult.InvalidId; break; default: executeResult = NotificationResult.OperationError; break; } return executeResult; } } 

This is how I test the code:

  PrivateType privateHelperType = new PrivateType(typeof(NotificationContext)); var actual = (NotificationResult)privateHelperType.InvokeStatic( "GetExecuteResult", (short)1); var actual2 = (NotificationResult)privateHelperType.InvokeStatic( "GetExecuteResult", (short)0); //here is where i get the exception 

In the first call I get the expected result, in the second call I get an exception (I added a short opinion that perhaps the exception was because he did not find the method with int as a parameter).

Can anyone reproduce the behavior? Am I doing something wrong?

Thanks for your help.

+6
source share
3 answers

The problem is that there are two overloads of this method (there are others, but they are not important here):

The difference is that the second overload has a parameter of type BindingFlags , which is enum . And when you pass the literal 0 as the second parameter, this overload is selected because the literal 0 implicitly converted to any enum and does not use params is considered better than using it when resolving the overload. So basically

  • privateType.InvokeStatic("GetExecuteResult", 1) compiled into privateType.InvokeStatic("GetExecuteResult", new object[] { 1 })
  • privateType.InvokeStatic("GetExecuteResult", 0) compiled into privateType.InvokeStatic("GetExecuteResult", 0, new object[] { })

This is the cause of your problem. I think the cleanest way to avoid this is to create an array explicitly:

 privateType.InvokeStatic("GetExecuteResult", new object[] { 0 }) 

Except for your code, you are not passing the literal 0 method; you produced it first. According to the specification, BindingFlags overload BindingFlags not be selected in this case. But errors like this are a known error that will not be fixed because it will break some work programs.

+8
source

Interesting ... I was able to reproduce it, and found a way to fix it.

 short s = 0; var actual2 = (NotificationResult)privateHelperType.InvokeStatic( "GetExecuteResult", s); 
+3
source

I would try to make your class unsealed. This is pure speculation, but perhaps it is a subclassification of your NotificationContext as part of PrivateType.

My second recommendation is to download something like dotpeek: http://blogs.jetbrains.com/dotnet/2011/05/free-net-decompiler-is-available-for-early-access/ to see what PrivateType looks like . Understanding how this works will help you develop what is actually happening.

-3
source

Source: https://habr.com/ru/post/906260/


All Articles