15

Lets say we have a few interfaces defined in a .NET class library written in C#. Is there a way to implement these interfaces in a PowerShell script?

Call this a business need. We as a vendor, provide a few interfaces that are implemented by our customers to use our product. One of our customer wants to do this from PowerShell script.

6
  • Why do you want to do this? PowerShell is dynamically typed itself. Commented Aug 18, 2015 at 6:37
  • 1
    @poke don't see what this has to do with his question, implementing an interface doesn't have anything to do with powershell's typing, maybe he needs to pass his objects to a .net method that expects an IEnumerable<HisInterface> for example Commented Aug 18, 2015 at 6:40
  • @RonanThibaudau My question has to do with finding out about the X of this Y. Commented Aug 18, 2015 at 6:44
  • @poke our customer wants to implement our interfaces in their PowerShell scripts. No one ever asked this before. Commented Aug 18, 2015 at 6:48
  • 2
    possible duplicate of Powershell. Create a class file to hold Custom Objects? Commented Aug 18, 2015 at 6:50

3 Answers 3

21

Here's a simple example with PowerShell 5.0 implementing the .Net IEqualityComparer interface:

Class A:System.Collections.IEqualityComparer {
  [bool]Equals($x,$y)  { return $x -eq $y        }
  [int]GetHashCode($x) { return $x.GetHashCode() }
}
[A]$a=[A]::new()
$a.Equals(1,1) -- returns True
$a.Equals(1,2) -- returns False
$a.GetHashCode("OK") -- returns 2041362128

You could even have a class (called A), which inherits from another class (called B) and implements IEqualityComparer:

Class A:B,System.Collections.IEqualityComparer {
Sign up to request clarification or add additional context in comments.

Comments

8

You can use Add-Type to define the class in C#, JScript, or VBScript. When there's a vendor-supplied assembly involved, it just has to be loaded prior to the Add-Type call, with another call to Add-Type:

$sourceCode = @"
    public class CustomerClass : Vendor.Interface
    {
         public bool BooleanProperty { get; set; }
         public string StringProperty { get; set; }
    }
"@    # this here-string terminator needs to be at column zero

$assemblyPath = 'C:\Path\To\Vendor.dll'
Add-Type -LiteralPath $assemblyPath
Add-Type -TypeDefinition $sourceCode -Language CSharp -ReferencedAssemblies $assemblyPath

$object = New-Object CustomerClass
$object.StringProperty = "Use the class"

Comments

5

EDIT: It seems you can now implement interfaces in powershell 5.0. This answer applies to powershell 4.0 or earlier.

Although you cannot implement interface from powershell directly, you can pass powershell delegates to .NET code. You could provide empty implementation of interface accepting delegates in constructor, and construct this object from powershell:

public interface IFoo
{
    void Bar();
}

public class FooImpl : IFoo
{
    Action bar_;
    public FooImpl(Action bar)
    {
        bar_ = bar;
    }

    public void Bar()
    {
        bar_();
    }
}

And in powershell:

$bar = 
{ 
   Write-Host "Hello world!"
}

$foo = New-Object FooImpl -ArgumentList $bar
# pass foo to other .NET code

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.