【问题标题】:Can we implement .NET interfaces in PowerShell scripts?我们可以在 PowerShell 脚本中实现 .NET 接口吗?
【发布时间】:2015-11-10 23:02:20
【问题描述】:

假设我们在用 C# 编写的 .NET 类库中定义了一些接口。有没有办法在 PowerShell 脚本中实现这些接口?

将此称为业务需求。作为供应商,我们提供了一些由客户实现的接口以使用我们的产品。我们的一位客户希望通过 PowerShell 脚本执行此操作。

【问题讨论】:

  • 为什么要这样做? PowerShell 本身是动态类型的。
  • @poke 看不出这与他的问题有什么关系,实现一个接口与 powershell 的打字没有任何关系,也许他需要将他的对象传递给一个 .net 方法期望一个 IEnumerable 例如
  • @RonanThibaudau 我的问题与了解@​​987654321@有关。
  • @poke 我们的客户希望在他们的 PowerShell 脚本中实现我们的接口。以前从来没有人问过这个问题。

标签: c# .net powershell powershell-3.0


【解决方案1】:

这是一个使用 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

您甚至可以拥有一个类(称为 A),它继承自另一个类(称为 B)并实现 IEqualityComparer:

Class A:B,System.Collections.IEqualityComparer {

【讨论】:

    【解决方案2】:

    您可以使用Add-Type 在 C#、JScript 或 VBScript 中定义类。当涉及供应商提供的程序集时,只需在调用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"
    

    【讨论】:

      【解决方案3】:

      编辑:看来你现在可以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
      

      【讨论】:

        猜你喜欢
        • 2018-06-10
        • 2018-04-04
        • 2015-02-01
        • 2013-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多