Reputation: 564
public static void WaitUntilElementVisible(Action<string> preAction = null)
{
preAction?.Invoke();
}
static void Main(string[] args)
{
WaitUntilElementVisible((str) => PanelHandler("in"));
}
public static void PanelHandler(string className)
{
// do something
}
I want to execute PanelHandler("in")
if its not null inside the WaitUntilElementVisible()
method. However the Invoke()
expects a string. But the strange thing is that I'm already giving it a string when I do WaitUntilElementVisible(() => PanelHandler("in"));
how can I make Invoke use the string which I pass via lambda?
I want to call WaitUntilElementVisible()
in such a way that WaitUntilElementVisible()
will invoke PanelHandler
with "in"
.
Upvotes: 0
Views: 96
Reputation: 15190
Your WaitUntilElementVisible
is using an Action<string>
delegate which is simply a reference to a method that expects a string argument but it does not know anything about the concrete method you want to call, in your example, the reference being used is the anonymous method you create with your lambda expression (str) =>
, then, that method calls your actual method but you have already passed the reference of the original method!
If you convert the anonymous method to a regular one it is easier to understand what is happening:
static void Main(string[] args)
{
WaitUntilElementVisible(MyActionMethod);
}
public static void WaitUntilElementVisible(Action<string> preAction = null)
{
preAction?.Invoke();
}
public static void MyActionMethod(string str)
{
PanelHandler("in");
}
public static void PanelHandler(string className)
{
Console.WriteLine(className);
}
As you can see the reference you are passing is to MyActionMethod
and not to PanelHandler
and the str
parameter is not used at all.
So you need to add a string argument to your method to pass the value and then you have the reference to the method and the value you need to pass:
static void Main(string[] args)
{
WaitUntilElementVisible(PanelHandler, "in");
}
public static void WaitUntilElementVisible(Action<string> preAction = null, string value = null)
{
preAction?.Invoke(value);
}
public static void PanelHandler(string className)
{
Console.WriteLine(className);
}
Or you can remove the string requirement and simply accept any method and then your code will work:
static void Main(string[] args)
{
WaitUntilElementVisible(() => PanelHandler("in"));
}
public static void WaitUntilElementVisible(Action preAction = null)
{
preAction?.Invoke();
}
public static void PanelHandler(string className)
{
Console.WriteLine(className);
}
Now of course, you are simply telling the compiler to invoke whichever method is referenced by your action delegate.
Another option is to use a dynamically typed language such as Python ;-)
def waitUntilElementVisible(preAction = None):
if preAction is not None:
preAction()
def panelHandler(className):
print(className)
if __name__=='__main__':
waitUntilElementVisible(panelHandler('in'))
In this case this will work because references are resolved at run-time and not at compile time like in .NET.
Upvotes: 1
Reputation: 11
The problem is due to your declaration of WaitUntilElementVisible, the declaration
public static void WaitUntilElementVisible(Action<string> preAction = null)
declares a delegate that will take a string parameter, that is, it is expecting that the call to WaitUntilElementVisible will look like:
WaitUntilElementVisible(someString => PanelHandler(someString));
Which would be the useful in the situation where the WaitUntilElementVisible was to provide the string to your delegate.
What you want is for the declaration of WaitUntilElementVisible to be
public static void WaitUntilElementVisible(Action preAction = null)
Which means that it expects a delegate that takes no arguments.
Upvotes: 1