-1

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.

TDub
  • 23
  • 5
  • What's the error? The code from the linked question's answer should work no matter what the method is. – Heretic Monkey Dec 07 '18 at 21:59
  • The error is: Object reference not set to an instance of an object. I can't see anything saying that a method with a parameter would behave any different, hence the call for help. I remove the parameter from the offending method to test and it sees the attribute. Can't figure it out. – TDub Dec 07 '18 at 22:13
  • Can you edit your post to include the declaration of the method you're trying to invoke and the string literal you are using for `AMethodNameFrom_AClassInTheProject`? – John Wu Dec 07 '18 at 23:04

1 Answers1

0

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.

madreflection
  • 4,744
  • 3
  • 19
  • 29
  • That was the issue. Intellisense is saying that there isn't an overload that takes only the name in my framework .NET 4.5, though I do see the overload on other frameworks on microsofts site. Thank You for the help – TDub Dec 07 '18 at 22:41
  • Are you looking for `GetRuntimeMethod` or `GetMethod`? `GetMethod` with only the name should be in .NET 4.5 according to this: https://apisof.net/catalog/System.Type.GetMethod(String) – madreflection Dec 07 '18 at 22:51