How do I retrieve the values for parameters if the parameter name and field name are different using reflection?

1.1k Views Asked by At

How do I retrieve the values for parameters if the parameter name and field name are different? I have researched so far for about 2 days and not able to find a solution. Any help appreciated. I have provided the sample code below.

class Class1
{        
    public void method(string firstname, string lastname, out string name)
    {
        name = lastname + ", " + firstname;
    }
}

class Names
{
    public string First
    {
        get;
        set;
    }
    public string Last
    {
        get;
        set;
    }
}

class FullName
{
    public string Full
    {
        set;
        get;
    }
}
private void btnExecute_Click(object sender, EventArgs e)
{
        Class1 cls = new Class1();
        Names request = new Names();
        request.First = "Mohanraj";
        request.Last = "Devadoss";
        FullName response = new FullName();

        MethodInfo methodInfo = cls.GetType().GetMethod("method");
        ParameterInfo[] parameters = methodInfo.GetParameters();
        ParameterInfo returnParameter = methodInfo.ReturnParameter;
        var inputParameters = new object[parameters.Length];

        Type requestType = request.GetType();
        PropertyInfo[] properties = requestType.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
        object result = null;
        int count = 0;
        const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

        foreach (ParameterInfo parameter in parameters)
        {
            PropertyInfo property = requestType.GetProperty(parameter.Name);
            FieldInfo field = requestType.GetField(parameter.Name);
            MemberInfo[] members = requestType.GetFields(bindingFlags).Cast<MemberInfo>().Concat(requestType.GetProperties(bindingFlags)).ToArray();

            object value = null;

            try { value = property.GetValue(request, null); }
            catch { value = null; }
            try
            {
                value = field.GetValue(request);
            }
            catch
            {
                value = null;
            }

            if (parameter.ParameterType.IsByRef)
            {
                value = null;
            }

            inputParameters[count] = value;
            count = count + 1;
        }

        result = methodInfo.Invoke(cls, inputParameters);
}
1

There are 1 best solutions below

0
On

There are a couple of things wrong with your code.

First, you are using requestType.GetProperty(parameter.Name). parameter.Name can be firstname, lastname or name. This can never equal one of the properties of the Names class and so it will always return null.

Then you are using the same syntax to retrieve a field. However, if you would execute the following code: requestType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic), you would see that there are two generated backing fields for your automatic properties with made up names. It makes no sense to retrieve both the property and the backing field.

Is it really necessary to use reflection? You know all the properties and methods at compile time. If possible, just avoid reflection.

If that's not possible, you should use reflection to get the property. You can do this by mapping the parameter.Name value to one of the possible properties of your Names class. Something like:

if (parameter.Name == "firstname")
{
    property = requestType.GetProperty("First", BindingFlags.Instance | BindingFlags.Public);
}