8

I have a C# method say:

MyMethod(int num, string name, Color color, MyComplexType complex)

Using reflection, how can I distinctly identify each of the parameter types of any method? I want to perform some task by parameter type. If the type is simple int, string or boolean then I do something, if it is Color, XMLDocument, etc I do something else and if it is user defined type like MyComplexType or MyCalci etc then I want to do certain task.

I am able to retrieve all the parameters of a method using ParameterInfo and can loop through each parameter and get their types. But how can I identify each data type?

foreach (var parameter in parameters)
{
    //identify primitive types??
    //identify value types
    //identify reference types

}

Edit: this is apart of my code to create a propert grid sort of page where I want to show the parameter list with data types for the selected method. If the parameter has any userdefined type/reference type then I want to expand it further to show all the elements under it with datatypes.

Sri Reddy
  • 6,832
  • 20
  • 70
  • 112
  • What exactly do you want to do with complex type parameter? – Victor Haydin Jan 04 '11 at 21:37
  • You've got a *far* bigger problem than that, how are you going to generate the proper *value* to make the call? Think this through and the answer will pop out. Look at the *dynamic* keyword. – Hans Passant Jan 04 '11 at 21:48
  • @mace, basically, I am trying to create a property page sort of thing, where the page should show the parameters and the type. If it is a reference type like MyComplexType, then I am expanding that type to find other type within it. If it is not a reference type like int, string or color then I need not check inside it. Hope you got what I mean. – Sri Reddy Jan 04 '11 at 21:57

2 Answers2

15

Make use of ParameterInfo.ParameterType

 using System;
 using System.Reflection;

 class parminfo
 {
    public static void mymethod (
       int int1m, out string str2m, ref string str3m)
    {
       str2m = "in mymethod";
    }

    public static int Main(string[] args)
    {
       Console.WriteLine("\nReflection.Parameterinfo");

       //Get the ParameterInfo parameter of a function.

       //Get the type.
       Type Mytype = Type.GetType("parminfo");

       //Get and display the method.
       MethodBase Mymethodbase = Mytype.GetMethod("mymethod");
       Console.Write("\nMymethodbase = " + Mymethodbase);

       //Get the ParameterInfo array.
       ParameterInfo[]Myarray = Mymethodbase.GetParameters();

       //Get and display the ParameterInfo of each parameter.
       foreach (ParameterInfo Myparam in Myarray)
       {
          Console.Write ("\nFor parameter # " + Myparam.Position 
             + ", the ParameterType is - " + Myparam.ParameterType);
       }
       return 0;
    }
 }

If you need to check the System.Type once retrieved you can use IsPrimitive and IsByRef as mentioned by David. In addition you can also use IsValueType. There are a significant number of Is* properties within the System.Type class. Your best bet would be to check the MSDN documentation on each Is* property ie...IsClass states...

Gets a value indicating whether the Type is a class; that is, not a value type or interface.

Therefore one could deduce that IsValueType does not need to be called. Keep in mind that a given type can return true across multiple properties in that IsClass could return true AND IsPassByRef could return true. Perhaps provide logic for the known CLR types since those will not change and you know those ahead of time and then build in the logic for complex types as defined by the user. You could take the approach of building in the logic to do this for the CLR types as well; either way would work.

Aaron McIver
  • 24,527
  • 5
  • 59
  • 88
  • I was able to get the type of the parameter. Now how will I identify each type.. whether it is a reference type or value type or a primitive type? I want a generic code to do it for any method passed to it. – Sri Reddy Jan 04 '11 at 21:54
  • ParameterType returns a System.Type, which has a property called IsByRef (tells you if it's a reference type) and another called IsPrimitive. – Amanda Mitchell Jan 04 '11 at 23:06
  • @user465876 Added additional commentary as mentioned by David in addition a reference to IsValueType – Aaron McIver Jan 05 '11 at 04:15
  • @Dave,Aaron, thanks for the response. I guess it is not working out. I compared the properties for Int32, String, Color, MyComplexType/MyClass and the results were not very helpful. Int32 and Color has IsValueType=true, IsPrimitive=true, IsClass=False and IsByRef=false. For String, MycomplexType/MyClass it is IsValueType=false, IsPrimitive=false, IsClass=true and IsByRef=false. I am worried even if I put all those conditions mentioned above, how to make sure it works for every type that user defined in a method? I can't check each and every type. Can attribute property help in any way? – Sri Reddy Jan 05 '11 at 14:24
  • @user465876 Added additional commentary in post...it boils down to making use of the Is* properties to define the logistical path each type should take. – Aaron McIver Jan 05 '11 at 14:38
2

To get the actual Type of the parameter use the ParameterType on the ParameterInfo value. With that value there are several ways you can use it to identify the type. The easiest is with a direct comparison to a known type

if (parameter.ParameterType == typeof(int)) { 
  ...
}

Or in cases where the type is not available a name match can be used (although this is a bit flakier as refactor operations may miss the string constant and silently break the application)

if (parameter.ParameterType.Name == "TheTypeName") {
  ...
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • This way will restrict me to make the code generic for any method.. or I have to check for each and every type that exist in C#. I would like to have a generic way to check the parameter type on the fly. – Sri Reddy Jan 04 '11 at 21:52
  • @user465876 if primitive is all you care about then just use the `IsPrimitive` property. – JaredPar Jan 04 '11 at 21:57
  • I think I could explain properly. Actually I want to write a generic code that will read a method name and get all the parameters and then write them into a page with it's type. If the type is reference type (user defined) then it should expand it further to check the types inside it and write it to the page. Something like a property grid. I care about each type so that I know which one to exand more. – Sri Reddy Jan 04 '11 at 22:04