我们可以在 PowerShell 脚本中实现 .NET 接口吗?
Can we implement .NET interfaces in PowerShell scripts?
假设我们在用 C# 编写的 .NET class 库中定义了一些接口。有没有办法在 PowerShell 脚本中实现这些接口?
称之为业务需求。作为供应商,我们提供了一些由我们的客户实现以使用我们的产品的接口。我们的一位客户希望通过 PowerShell 脚本执行此操作。
编辑:看来您现在可以 implement interfaces in powershell 5.0。此答案适用于 powershell 4.0 或更早版本。
虽然不能直接从powershell实现接口,但是可以通过powershell delegates to .NET code。您可以在构造函数中提供接受委托的接口的空实现,并从 powershell 构造此对象:
public interface IFoo
{
void Bar();
}
public class FooImpl : IFoo
{
Action bar_;
public FooImpl(Action bar)
{
bar_ = bar;
}
public void Bar()
{
bar_();
}
}
在 powershell 中:
$bar =
{
Write-Host "Hello world!"
}
$foo = New-Object FooImpl -ArgumentList $bar
# pass foo to other .NET code
这是一个使用 PowerShell 5.0 实现 .Net IEqualityComparer 接口的简单示例:
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
您甚至可以拥有一个 class(称为 A),它继承自另一个 class(称为 B)并实现 IEqualityComparer:
Class A:B,System.Collections.IEqualityComparer {
您可以使用 Add-Type
在 C#、JScript 或 VBScript 中定义 class。当涉及供应商提供的程序集时,只需在调用 Add-Type
之前加载它,然后再调用 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"
假设我们在用 C# 编写的 .NET class 库中定义了一些接口。有没有办法在 PowerShell 脚本中实现这些接口?
称之为业务需求。作为供应商,我们提供了一些由我们的客户实现以使用我们的产品的接口。我们的一位客户希望通过 PowerShell 脚本执行此操作。
编辑:看来您现在可以 implement interfaces in powershell 5.0。此答案适用于 powershell 4.0 或更早版本。
虽然不能直接从powershell实现接口,但是可以通过powershell delegates to .NET code。您可以在构造函数中提供接受委托的接口的空实现,并从 powershell 构造此对象:
public interface IFoo
{
void Bar();
}
public class FooImpl : IFoo
{
Action bar_;
public FooImpl(Action bar)
{
bar_ = bar;
}
public void Bar()
{
bar_();
}
}
在 powershell 中:
$bar =
{
Write-Host "Hello world!"
}
$foo = New-Object FooImpl -ArgumentList $bar
# pass foo to other .NET code
这是一个使用 PowerShell 5.0 实现 .Net IEqualityComparer 接口的简单示例:
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
您甚至可以拥有一个 class(称为 A),它继承自另一个 class(称为 B)并实现 IEqualityComparer:
Class A:B,System.Collections.IEqualityComparer {
您可以使用 Add-Type
在 C#、JScript 或 VBScript 中定义 class。当涉及供应商提供的程序集时,只需在调用 Add-Type
之前加载它,然后再调用 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"