Search code examples
c#reflectionattributesgetgauge

Read the value of an attribute from a method with parameters


I was looking for a way to get the value of an attribute and send it to a report I have to make. The short of it is I found an answer when a method has no parameters but any methods with paramaters throws an error.

My initial question of how to Read the value of an attribute from a method was answered by this question (Read the value of an attribute of a method)

Here is the code that has been working

public static void WriteStepNamesOfMethodToReport(Type classType, string methodName)
{
    MethodInfo methodInfo = classType.GetRuntimeMethod(methodName, new Type[] { });
    Attribute[] attributeList = (System.Attribute[])methodInfo.GetCustomAttributes(typeof(Step), true);

    GaugeMessages.WriteMessage("---------------------");
    foreach (Attribute attr in attributeList)
    {
        Step a = (Step)attr;
        GaugeMessages.WriteMessage("Executed Step - {0}", a.Names.ElementAt(0));
    }
    GaugeMessages.WriteMessage("---------------------");
}

This is how I set up the variables to send (and yes I could make that one line, but I define it in one place and use it in many so that is the way it needs to be)

Type classType = typeof(AClassInTheProject);
GenericHelpers.WriteStepNamesOfMethodToReport(classType, nameof(AMethodNameFrom_AClassInTheProject));

The line of Code that starts with Attribute[] attribute.... is throwing an error when I try to provide a method (methodName) that has parameters in it. When I enter the "methodName" it is always just like that (no parenthesis as it will not accept those). The error produced says:

Object reference not set to an instance of an object.

I tried removing the parameter temporarily from the specific method that was throwing an error and it saw the Step attribute that I was looking for and output it to the report.

Here is the basic layout of the class I am using (same setup as all the non-parameter methods that work).

class AClassInTheProject
{
    [Step("Perform the Step For AMethodNameOne"]
    AMethodNameOne() // This one works
    {
        // Code
    }

    [Step("Perform the Step For AMethodNameTwo"]
    AMethodNameTwo(string parameterA) // This one doesn't work
    {
        // Code
    }
}

Background: This is for a Gauge UIAutomation project. I need to run some steps in the UI Automation under logical conditions (If A Perform Step ...) which Gauge does not provide support for. All steps performed need to be output to the final report (GaugeMessages.....). This is a C# project. My need is not common among people int the Gauge community so it was not deemed priority enough to include a fix in the source code (which is why I'm doing this workaround). Hopefully that's detailed enough.


Solution

  • At the root, this is a NullReferenceException problem.

    That call to GetRuntimeMethod is saying "give me a method by this name with no parameters". It's returning null because the method you want has parameters. It works when you remove the parameter because then it matches the "no parameters" condition.

    If you want specific parameter types, specify them, e.g. new Type[] { typeof(string) }.

    If you want any number and type of parameters, use the GetMethod overload that doesn't take a Type[] (assuming there's only one method by that name, otherwise you'll get a different exception) or use GetMethods and find the method you want from the array it returns.