PrivateObject ignoring integer argument if it is 0

Отвечено PrivateObject ignoring integer argument if it is 0

  • 16 марта 2012 г. 14:35
     
      С кодом

    I ran into a strange problem with PrivateObject that seems to ignore an integer argument given to the Invoke call if the value is "0". See the basic example below:

    using System;
    using System.Reflection;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace TestProject1
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestMethod1()
            {
                var sut = new MyClass();
                var sutPrivate = new PrivateObject(sut);
    
                // Passes:
                Assert.AreEqual(1, (int)sutPrivate.Invoke("MyMethod", 1));
    
                // MissingMethodException:
                Assert.AreEqual(0, (int)sutPrivate.Invoke("MyMethod", 0));
                // MissingMethodException:
                Assert.AreEqual(0, (int)sutPrivate.Invoke("MyMethod", new [] {typeof(UInt32)}, 0));
    
                // Passes!
                Assert.AreEqual(0, (int)sutPrivate.Invoke("MyMethod", BindingFlags.NonPublic | BindingFlags.Instance, 0));
            }
        }
    
        internal class MyClass
        {
            private int MyMethod(int arg)
            {
                return arg;
            }
        }
    }
    Note that the first invoke works as expected because the integer argument is "1". Second one fails with MissingMethodException and it doesn't even help to specify a type array as is done in the third attempt. Strangely it helps to specify BindingFlags.NonPublic and BindingFlags.Instance, which should be giving by using PrivateObject. Looking at the IL code I can see that the compiler omits the argument completely so MissingMethodException happens for a reason.

    This seems like an error in the Invoke overload on PrivateObject or in the underlaying reflection calls, or have I missed something?


    Tore Østergaard
    Oticon A/S, Denmark

Все ответы

  • 20 марта 2012 г. 7:35
    Модератор
     
     

    Hi Tore,

    Thank you for posting in the MSDN forum.

    I try to repro this issue. Then I use the tool .NET Reflector to check it

    1)Assert.AreEqual(0, (int)sutPrivate.Invoke("MyMethod", (object)0));

    Result: Failed

    I get the result like the following screen shot with that tool.

    2)Assert.AreEqual(1, (int)sutPrivate.Invoke("MyMethod", 1));

    See:

    Result: Passed

    3)Assert.AreEqual(0, (int)sutPrivate.Invoke("MyMethod", (object)0));

    Result: Passed

    4)int i = 0;

      Assert.AreEqual(0, sutPrivate.Invoke("MyMethod", i));

    Result: Passed

    As my understanding that if we use the step1 with 0, we just get an array like the object[0],  it has the return value, but it could be the int or double or others, I think it is related to the Boxing and Unboxing, see http://msdn.microsoft.com/en-us/library/yz2be5wk(v=vs.100).aspx.

    So if possible, use the workaround provided by us, hope it helps.

    Best Regards,


    Jack Zhai [MSFT]
    MSDN Community Support | Feedback to us

  • 20 марта 2012 г. 12:00
     
     

    Thank you for your reply Jack.

    Your solution 4 does indeed work, but put a "const" keyword in front of the declaration of the i variable (which Resharper will help you remember) and you get back into the MissingMethodException.

    I think that I will use the boxing workaround, but I still think that it is a bug somewhere in the framework since I can work around it by using another overload to the Invoke method.


    Tore Østergaard
    Oticon A/S, Denmark

  • 21 марта 2012 г. 2:03
    Модератор
     
     Отвечено

    Hi Tore,

    Glad to receive your reply.J

    As my understanding, it is related to the Boxing and Unboxing. But if you think it is a feedback, you can submit this feedback to Microsoft Connect feedback portal: http://connect.microsoft.com, Microsoft engineers will evaluate them seriously. Thanks for your understanding.

    Best Regards,


    Jack Zhai [MSFT]
    MSDN Community Support | Feedback to us

  • 21 марта 2012 г. 12:19
     
     
    I have created a Microsoft Connect feedback ticket: http://connect.microsoft.com/VisualStudio/feedback/details/732374/zero-integer-argument-is-seen-as-empty-array

    Tore Østergaard
    Oticon A/S, Denmark