1

I created a dll in C# and then called this dll in PowerShell. Below I have a method called TypeName<T>()

public class ClassTest
{
    public string TypeName<T>() where T : FlaUI.Core.AutomationElements.AutomationElement
    {
        return typeof(T).FullName;
    }
}

I'm using the FlaUI.Core reference from Nuget, that is, I'm just going to expect types from this reference:

where T : FlaUI.Core.AutomationElements.AutomationElement

In Powershell, how do I call this generic method? I've tried this and it doesn't work:

add-type -path C:\Users\unknow\source\repos\AutomationDLL\AutomationDLL\bin\Debug\My.dll
add-type -path C:\Users\unknow\source\repos\AutomationDLL\AutomationDLL\bin\Debug\FlaUI.Core.dll
add-type -path C:\Users\unknow\source\repos\AutomationDLL\AutomationDLL\bin\Debug\FlaUI.UIA3.dll

$instance = new-object ClassTest    
$instance.TypeName[[FlaUI.Core.AutomationElements.Button]]();

It is giving this error:

On line:7 character:59
+ $instance.TypeName[[FlaUI.Core.AutomationElements.Button]]();
+ ~
Unexpected token '(' in expression or statement.
On line:7 character:60
+ $instance.TypeName[[FlaUI.Core.AutomationElements.Button]]();
+~
An expression was expected after '('.
    + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken
mklement0
  • 382,024
  • 64
  • 607
  • 775
megaultron
  • 399
  • 2
  • 15
  • Does this answer your question? [How do I call a parameterless generic method from Powershell v3?](https://stackoverflow.com/questions/18774889/how-do-i-call-a-parameterless-generic-method-from-powershell-v3) – Charlieface Mar 28 '23 at 01:40
  • @Charlieface, we originally had that as a duplicate, but decided against it, given that the question at hand at least seemingly tries to use the new v7.3+-only syntax for invoking generic method withs explicit type arguments, whereas the linked question is about v3. – mklement0 Mar 28 '23 at 14:06

1 Answers1

4

Only PowerShell (Core) 7.3+ supports calling generic methods with explicit type arguments - however, use only enclosing […] - do not also enclose the type argument(s) in […]:

# PS 7.3+ only
# Note: Only *one* set of [...], around the list of all type arguments,
#       not also around the individual type(s).
[ClassTest]::new().TypeName[FlaUI.Core.AutomationElements.Button]()

See the conceptual about_Calling_Generic_Methods help topic.


In PowerShell 7.2- (including in Windows PowerShell), direct calls to generic methods are only possible if the type argument(s) can be inferred from the parameter values (arguments), because these versions have no syntax for specifying type arguments explicitly.

Otherwise - such as in your case, given that your method has no parameters (other than a type parameter) - you must use reflection:

$instance = [ClassTest]::new()
[ClassTest].
  GetMethod('TypeName', [type[]] @()).
  MakeGenericMethod([FlaUI.Core.AutomationElements.Button]).
  Invoke($instance, @())
  • .GetMethod('TypeName', [type[]] @()) finds the overload of method TypeName that has no parameters ([type[]] @()) - since there is only one overload in your case, you could omit the second argument.

  • .MakeGenericMethod([…]) instantiates the method with the desired type argument.

  • .Invoke($instance, @()) then invokes the type-instantiated method on instance $instance with no arguments (@(), the empty array).

mklement0
  • 382,024
  • 64
  • 607
  • 775