none
Reflection: Type.GetMethod using int for enum parameter

    Question

  • Hello,

    we are using a "device system" here which is using reflection to invoke methods.

    Consider this class:

    public class Test
    {
      public void SetDayOfWeek(DayOfWeek day)
      {
        //...
      }
    }
    

    Using

    MethodInfo m =
      typeof(Test).GetMethod(
        "SetDayOfWeek",
        BindingFlags.Instance | BindingFlags.Public,
        null,
        new Type[] { typeof(int) }, null);
    

    m is null - probably because I am passing an int as the enum parameter DayOfWeek.

    Is there any way to have an int be accepted as enum parameter in such a lookup?

    regards,

    Florian

    Tuesday, October 26, 2010 8:02 AM

All replies

  • Hi

    You have to use a type of day of the week instead of int else you ll get a null method info

    but you still can pass 1 as parameter, this code worked for me and displays Monday

    public

     

     

    class Test

    {

     

     

    public void SetDayOfWeek(DayOfWeek day)

    {

     

     

    Console.WriteLine(day.ToString());

    }

    }

     

     

     

    class Program

    {

     

     

    static void Main(string[] args)

    {

     

     

    MethodInfo m =typeof(Namespace.Test).GetMethod("SetDayOfWeek", BindingFlags.Instance | BindingFlags.Public, null,

     

     

    new Type[] { typeof(int) }, null);

    m =

     

    Type.GetType("Namespace.Test").GetMethod("SetDayOfWeek", new Type[] { typeof(DayOfWeek) });

     

     

    Test t = new Test();

    m.Invoke(t,

     

    new object[] { 1 });

     

     

    Console.Read();

    }

    }


    The complexity resides in the simplicity
    • Proposed as answer by DomTac Monday, June 20, 2011 9:01 AM
    Tuesday, October 26, 2010 3:53 PM
  • Hi MASNSN,

    thanks for pointing that out but it does not help since at runtime I only have an int as parameter. So finding the method is the problem - not invoking it.

    Anybody has an idea if maybe a custom "binder" might help?

    regards,

    Florian

    ps: your code block is completely broken... ;-)

    Wednesday, October 27, 2010 6:47 AM
  • F. Schricker,

    But you can cast int type to DayOfTheWeek and cast it back. Or you can use another overriding of GetMethod() to find method via reflection:

    MethodInfo m =

     (typeof(Test)).GetMethod(

    "SetDayOfWeek",

    BindingFlags.Instance | BindingFlags.Public);

    Of course your code won't work because Type[] parameter should describe input parameters of the result method and if you use it it should work correctly (otherwise you can create an overriding of the SetDayOfWeek method: SetDayOfWeek (int i) and which behavior of the Type.GetMethod do you expect in this case?)

    Wednesday, October 27, 2010 7:20 AM
  • int day = (int)DayOfWeek.Saturday;
    Test test = new Test();
    MethodInfo m =  typeof(Test).GetMethod(
        "SetDayOfWeek",
          BindingFlags.Instance | BindingFlags.Public,
          null,  
          new Type[] { typeof(DayOfWeek)}, null
        );
    m.Invoke(test, new object[]{day});
    

    gimme some slamming techno!!!!
    Wednesday, October 27, 2010 7:20 AM
    Moderator
  • may need to cast it:
    m.Invoke(test, new object[]{(DayOfWeek)day});
    
    

    gimme some slamming techno!!!!
    Wednesday, October 27, 2010 7:20 AM
    Moderator
  • Hi F

    I see you situation. I suppose you can write Adapter pattern I mean an intermediate method that invokes the SetDayOfWeek and then you invoke this intermediate method

    suppose that

    public
     class
     Test
    {
     public
     void
     SetDayOfWeek(DayOfWeek day)
     {
      //...
    
     }
    }
    

    Is in another assembly and the code is not reachable so that you can change the parameter type of that method.

    You create a new extension method to that assemby

    static  public
     class
     TestExtension
    { static public void SetDayOfWeekExtension(this Test t,int day) {
          t.
    SetDayOfWeek(day);
      } }

    Then you can use that extension method instead of the instance one




    The complexity resides in the simplicity
    Wednesday, October 27, 2010 9:36 AM
  • You aren't using System.DayOfWeek???

    you can do something like this:

    using System;
    using System.Text;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using System.Reflection;
    
    namespace ReflectionTest.Test
    {
      namespace HiddenFromTest
      {
        public enum Hidden
        {
          Val1, Val2,
        }
    
        public class FooClass
        {
          public Hidden Value { get; private set; }
    
          public void SetValue(Hidden value)
          {
            Value = value;
          }
        }
      }
    
      [TestClass]
      public class HiddenNamespaceReflection
      {
        static object GetFromHidden()
        {
          return new HiddenFromTest.FooClass();
        }
      
        [TestMethod]
        public void TestMethod1()
        {
          var bindings = BindingFlags.Instance | BindingFlags.Public;
          object test = GetFromHidden();
          Assert.IsInstanceOfType(test, typeof(HiddenFromTest.FooClass));
          Assert.AreEqual(HiddenFromTest.Hidden.Val1, (test as HiddenFromTest.FooClass).Value);
          var methodInfo = (from mi in test.GetType().GetMethods(bindings)
                let args= mi.GetParameters()
                where mi.Name == "SetValue"
                && args.Length == 1
                && args[0].ParameterType.IsEnum
                && args[0].ParameterType.Name == "Hidden"
                select mi).FirstOrDefault();
          Assert.IsNotNull(methodInfo);
          int i = 1;
          methodInfo.Invoke(test, new object[] { i });
          Assert.AreEqual(HiddenFromTest.Hidden.Val2, (test as HiddenFromTest.FooClass).Value);
        }
       
      }
      
    }
    
    

    gimme some slamming techno!!!!
    Wednesday, October 27, 2010 4:18 PM
    Moderator
  • Hi,

    sorry for coming back this late.

    So the basic problem still is that I have only reflection at hand at runtime. There is no way to cast to a specific type before invoking. It's all "common" code which needs to work for all sorts of calls on different types with different parameters.

    So I guess I need to manually search the method which best fits the given parameters in case System.Type.GetMethod fails.

    Additionally I'd still like to know if anybody has a clue about using the Binder class with GetMethod. Might using some suitable class help?

    regards,
    Florian

    Sunday, November 07, 2010 10:16 AM
  • You can define a new property of type DayOfWeek in the class Test. Let's call this property uselessProp.

     

    Then use:
    PropertyInfo uselessInfo =  typeof(Test).GetProperty("uselessProp");
    Type enumType = uselessInfo.PropertyType;

    Now just call
    typeof(Test).GetMethod(
     "SetDayOfWeek",
     BindingFlags.Instance | BindingFlags.Public,
     null,
     new Type[] { enumType  }, null


    Hope this helps..

     

     

    Original credit to:

    http://www.codeproject.com/KB/dotnet/EnumReflection.aspx

     

    for the idea..

    Tuesday, June 14, 2011 9:01 PM