2

I have the following sample C# class:

public static class Class1
{
    public static string Method1(Expression<Func<string>> efs)
    {
        return efs.Compile().Invoke();
    }
}

To call this from C# it's as easy as:

Class1.Method1(() => "Hello World");

I can not for the life of me figure out how to call this from Powershell. My last attempt is:

Add-Type -Path "ClassLibrary1.dll"
$func = [Func[string]] { return "Hello World" }
$exp = [System.Linq.Expressions.Expression]::Call($func.Method);
[ClassLibrary1.Class1]::Method1($exp)

But this results in an error:

Exception calling "Call" with "1" argument(s): "Incorrect number of arguments supplied for call to method 'System.String lambda_method(System.Runtime.CompilerServices.Closure)'"
At C:\Users\Mark\Documents\Visual Studio 2015\Projects\ClassLibrary1\ClassLibrary1\test.ps1:4 char:1
+ $exp = [System.Linq.Expressions.Expression]::Call($func.Method);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException
+ $exp = [System.Linq.Expressions.Expression]::Call($func.Method);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException

I believe my $func is incorrect; any ideas?

10
  • I don't see an overload of Expression.Call that takes a single argument. That is what the error is telling you as well. Commented Aug 3, 2017 at 15:47
  • @DavidG, no, that results in Cannot convert argument "efs", with value: "System.Func1[System.String]", for "Method1" to type "System.Linq.Expressions.Expression1[System.Func1[System.String]]", which is why I was trying to create an Expression` from the Func. Commented Aug 3, 2017 at 15:55
  • @JasonBoyd, good point, when I type the analogous in C# Func<string> func = () => "Hello World"; Expression.Call(func.Method);, it's using the signature: public static MethodCallExpression Call(MethodInfo method, params Expression[] arguments), now I'm stuck trying to figure out how to call that... Commented Aug 3, 2017 at 15:58
  • That's interesting. When I try that in LinqPad I get Static method requires null instance, non-static method requires non-null instance.Parameter name: method Commented Aug 3, 2017 at 16:15
  • You're also trying to convert a Func to an Expression which isn't really possible. Does it need to be an Expression? Because that would work very simply. Commented Aug 3, 2017 at 16:17

1 Answer 1

4

Ok, figured it out (thanks to @DavidG for the link). The key was to write out the System.Linq.Expressions.Expression tree in C# first. Then, converting to Powershell was easy after that:

So, in C# this:

Class1.Method1(() => "Hello World");

is analogous to:

var exp = Expression.Constant("Hello World", typeof(string));
var lamb = Expression.Lambda<Func<string>>(exp);
Class1.Method1(lamb);

In Powershell:

$exp = [System.Linq.Expressions.Expression]::Constant("Hello World", [string]);
$lamb = [System.Linq.Expressions.Expression]::Lambda([Func[string]], $exp);
[ClassLibrary1.Class1]::Method1($lamb);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.