如何在其他Add-Type类型定义中访问Add-Type定义的类型?

d58*_*884 5 powershell

如何访问Add-Type -TypeDefinition "..."另一个定义的类型Add-Type -TypeDefinition "..."

在下面的代码示例中,尽管名称空间相同,但编译器无法找到该UserCode类型.

Add-Type -TypeDefinition @"
namespace SampleCode {
    public struct UserCode {
         public string Name;
         public string Id;
    }
}
"@

#.... do something ....

Add-Type -TypeDefinition @"
namespace SampleCode {
    public struct UserInformation {
        public UserCode User;
        public string Note;
    }
}
"@
# => Error ... Add-Type : <temporary source path>(3) : The type or namespace name
# 'UserCode' could not be found (are you missing a using directive or an assembly
# reference?)
Run Code Online (Sandbox Code Playgroud)

Tre*_*van 10

为了从第二个.NET程序集引用第一个.NET程序集,您需要将第一个.NET程序集保留到磁盘.完成此操作后,可以使用cmdlet 的-ReferencedAssemblies参数从第二个.NET程序集引用第一个.NET程序集Add-Type.

重要信息:如果在两个不同的C#代码块中使用两个不同的命名空间,请确保using在第二个代码块中正确声明语句.

这是一个示例,向您展示如何:

  1. 动态编译新的.NET程序集到磁盘
  2. 导入引用磁盘上另一个程序集的动态程序集

第1部分 - 装配#1

必须将第一个.NET程序集输出到磁盘,以便我们可以引用它.因此,我们将使用cmdlet 的-OutputAssembly-OutputType参数Add-Type来创建它.

$Csharp = @"
using System;
using System.Reflection;

namespace Widget {
    public class UserCode {
        public static int GetValue() {
            return 2;
        }
    }
}
"@

# Define the output path for the new .NET Assembly
$OutputAssembly = '{0}\Widget.dll' -f $env:USERPROFILE;

# Compile the code and output a new .NET assembly
Add-Type -TypeDefinition $Csharp -OutputAssembly $OutputAssembly -OutputType Library;

# Load the .NET Assembly 
[System.Reflection.Assembly]::LoadFile($OutputAssembly);
Run Code Online (Sandbox Code Playgroud)

第2部分 - 大会#2

我们不必担心将第二个.NET程序集编译到磁盘,因为我们没有从任何其他程序集引用它.因此,我们可以简单地使用Add-Typecmdlet将其编译为临时的内存中程序集.我们必须确保使用该-ReferencedAssemblies参数来引用我们在第1部分中编译的.NET程序集.

# Now that we have a compiled .NET Assembly, we need to write our new code
# that references it (make sure to include all appropriate C# "using" statements)

# Define the second set of C# code
$CsharpCode2 = @"
using Widget;

namespace NASA {
    public class Shuttle {
        public int Boosters;
        public Shuttle() {
            this.Boosters = UserCode.GetValue();
        }
    }
}
"@;

# Try to compile the new code, but wait, we get an error ...
# ... because this code is dependent on the code contained in the
# Widget assembly
$Assembly2 = Add-Type -TypeDefinition $CsharpCode2 -PassThru;

# We have to reference the .NET Assembly that defines the UserCode type
$Assembly2 = Add-Type -TypeDefinition $CsharpCode2 -ReferencedAssemblies $OutputAssembly -PassThru;

# Now we can successfully create the NASA.Shuttle object;
$Shuttle = New-Object -TypeName NASA.Shuttle;

# View the number of boosters the Shuttle instance has
Write-Host -Object $Shuttle.Boosters;
Run Code Online (Sandbox Code Playgroud)