Skip to content

Instantly share code, notes, and snippets.

@jakobii
Last active February 28, 2019 04:52
Show Gist options
  • Save jakobii/eec3d56dc7a5492b1c87f6ba4b8b96d4 to your computer and use it in GitHub Desktop.
Save jakobii/eec3d56dc7a5492b1c87f6ba4b8b96d4 to your computer and use it in GitHub Desktop.
Embed C# In Powershell And Define Custom Interfaces!
# here is our custom interface. hopefully powershell will support creating
# interfaces natively soon. this is a simple example and is not ment to
# teach you c# syntax. sufice it to say an interface is a *contract*. an
# interface defines what methods and properties a class should have.
# interfaces allow you to contrain function parameters to only type that
# fullfill the *contract*. this is illistrated in the code below.
$CSharpCode = @"
public interface IFoo
{
void Bar();
}
"@
# compile the C# and make the code available in our powershell run time.
Add-Type -TypeDefinition $CSharpCode -Language 'CSharp' -Verbose
# define a function which will require that the agruments passed ot it
# "fullfill" (aka "Implement") the [IFoo] "contract" (aka "C# interface").
# we will do this by simple adding the [IFoo] type to one of our function
# parameters.
function test-foo ([ifoo]$i) {
$i | gm
$i.Bar()
}
# now we can create a type which implements our newly created
# [IFoo] interface. we do this by defining our class [test1]
# and giving it a base class of [IFoo]
class test1 : IFoo {
Bar() {
Write-Host "you just wrote some c# in powersell!" -f green
Write-Host "[test1] Implements [IFoo]" -f green
}
}
# to further illistrate the usefullness of interfaces let create a different
# class that also implements the [IFoo] interface. also notice that we can
# implement multiple interfaces by seperating them with comma's.
class test2 : IFoo, system.IComparable {
Bar() {
Write-Host "hurray for abstraction!" -f green
Write-Host "[test2] Implements [IFoo]" -f green
}
[int] CompareTo([object] $obj) {
return 42;
}
}
# while we are on the subject here are some things to keep in mind when it comes
# to class inheritants in powershell. its is a convention to start interface
# names with a capital "I". also powershell classes are only able to inherit the
# from the first base class, but they can implement many interfaces. if thats
# information went over your head, dont worry it not super important for this
# example. lets keep going!
# [test3] is an example of similar class, with the same method signature
# as [test1] and [test2] but notice we are not adding the [IFoo] interface
# this time. let see what happens.
class test3 {
Bar() {
Write-Host "This Should fail" -f red
}
}
# now lets test the function and make sure that only types that implement
# our c# interface will work with our function. this should work becuase
# [test1] implements [IFoo].
test-foo -i $([test1]::new())
# [test2] also works becuase it also implements the [IFoo] interface!
test-foo -i $([test2]::new())
# our [test3] class does not implement our c# interface, so if everything
# is working as expected this should fail and the catch{} block will run.
try {
test-foo -i $([test3]::new())
}
catch {
write-host '[test2] does not implement [IFoo]' -f green
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment