c# - 在 PowerShell 中提供 C# 抽象类的实现

标签 c# powershell powershell-7.0 intacct

我正在尝试创建 abstract class 的 PowerShell 类实现' 功能:

class ReadList : Intacct.SDK.Functions.AbstractFunction {

    [string]$ObjectName
    
    ReadList ([string]$ObjectName) {
        $this.ObjectName = $ObjectName
    }

    [void] WriteXml ( [Intacct.SDK.Xml.IaXmlWriter]$xml ) {

        $xml.WriteStartDocument()
        
        $xml.WriteStartElement("get_list")
        $xml.WriteAttributeString("object",$this.ObjectName)    
        $xml.WriteEndElement() # </get_list> 
    
        $xml.WriteEndDocument()
        $xml.Flush()
        $xml.Close()

    }

}

当我尝试使用它时,出现运行时异常:

Error during creation of type "ReadList". Error message: Method 'WriteXml' in type 'ReadList' from assembly 'PowerShell Class Assembly, Version=1.0.0.1, | Culture=neutral, PublicKeyToken=null' does not have an implementation.

我尝试添加 ref 标签:

[void] WriteXml ( [Intacct.SDK.Xml.IaXmlWriter][ref]$xml ) {

但是我得到了一个不同的错误:

Multiple type constraints are not allowed on a method parameter.

我做错了什么,还是我试图做的事情不受支持?

最佳答案

据我所知,这是不支持的。我无法找到一个好的解决方法,或者一个可以简洁解释它的资源。

从技术上讲,第二种实现是正确的,但根据错误 PowerShell 不支持方法参数的多个类型约束[1]
通常这并不是世界末日。问题是当从抽象类继承时,该类必须定义所有抽象方法 [2],因此具有签名 WriteXml (ref IaXmlWriter <ParameterName>) 的方法必须被定义。其他任何东西都会给出 Method 'WriteXml' ... does not have an implementation.

即使 PowerShell 支持多种类型约束,我也不认为这会按预期工作,因为 c#与 PowerShell 的 [ref] 不一样-[ref]创建它是为了支持 COM 对象,并且文档明确指出它不能用于对类成员进行类型转换[3]

我知道在这里可能有效的唯一解决方法是编写 ReadList c#中的类定义,并通过 Add-Type 添加到 PowerShell [4]...不太好。

这一切都超出了我的知识范围;也许有一个好的解决方案,并且有更多专业知识的人可以纠正我。


引用文献
[1] SO post that touches on this and [ref] (下同)

查看$Error.Exception.StackTrace , System.Management.Automation.ScriptBlock.Create 正在引发异常。无法进一步使用 PowerShell 5.1,但 PowerShell Core 文件包含对类方法参数的检查 here它指向 MultipleTypeConstraintsOnMethodParam 引发的异常。

Scripting.Classes.BasicParsing.Tests.ps1 检查多种类型将引发 MultipleTypeConstraintsOnMethodParam异常。

[2] 抽象类的派生类必须实现所有抽象方法。
Abstract and Sealed Classes and Class Members

[3] SO post that touches on this and multiple type constraints (同上)

类成员不支持 PSReference 类型
about_Classes

[4] Add a .NET type to a session


编辑
详细说明Add-Type解决方案

  • 使用ReferencedAssemblies传入Intacct.SDK.dll和依赖程序集。
  • 使用 [Reflection.Assembly] 加载这些程序集

使用Load()当指定版本或LoadFromPartialName()时仅包含名称 LoadFrom()指定路径时。

$Assemblies = @(
    'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'
    'System.Xml.ReaderWriter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
) |
foreach {
    [Reflection.Assembly]::Load($_)
}

$Assemblies += @(
    "$pwd/Microsoft.Extensions.Logging.Abstractions.dll"
    "$pwd/Intacct.SDK.dll"
) | foreach {
    [Reflection.Assembly]::LoadFrom($_)
}

Add-Type -TypeDefinition $Source -ReferencedAssemblies $Assemblies

关于c# - 在 PowerShell 中提供 C# 抽象类的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65888312/

相关文章:

c# - Xamarin Resource.designer.cs 不为新添加的文件生成引用

powershell - 将变量传递给 Foreach-Object PowerShell 7

powershell - 从 Powershell 5 移植到 Powershell 7 的功能失败,错误代码为 "object reference not set to an instance of an object"

conditional-operator - 三元比较输出新值

powershell - 无法获取文件掩码以在PowerShell中的多行WinSCP命令行中正常工作

c# - 使用 WPF 在 C# 中动态更改图像

c# - 自定义组件点击事件

C# ref 是像 C/C++ 中的指针还是 C++ 中的引用?

powershell - 如何将字符串变量与反斜杠连接起来以在 Powershell 中创建 UNC 路径

Powershell 查找和 move 项目