在Powershell构造函数中按类型重载?

问题描述 投票:3回答:1

我想知道,是否可以在Powershell中创建一个有两个构造函数的类,这两个构造函数都接受相同的 数目 的参数,但它们的类型不同。例如,我想创建类似下面的东西。

class User {
    [string]$GivenName
    [string]$Surname
    [string]$DisplayName
    [string]$Company
    [string]$PayrollNo
    [string]$Email
    [DateTime]$StartDate
    [DateTime]$LeaveDate

    User([Microsoft.ActiveDirectory.Management.ADAccount]$ADUser) {
        $this.GivenName   = $ADUser.GivenName
        $this.Surname     = $ADUser.Surname
        $this.DisplayName = $ADUser.Name
        $this.PayrollNo   = $ADUser.EmployeeID
        $this.Email       = $ADUser.EmailAddress
    }

    User([System.Array]$TraceUser) {
        $this.GivenName   = $TraceUser.'First Name'
        $this.Surname     = $TraceUser.Surname
        $this.DisplayName = "$($TraceUser.'First Name') $($TraceUser.Surname)"
        $this.Company     = $TraceUser.'Payroll Company'
        $this.PayrollNo   = $TraceUser.'Payroll No'
        $this.Email       = $TraceUser.'E-Mail'
        $this.StartDate   = [datetime]::ParseExact("$($TraceUser.'Start Date') 23:59",'dd/MM/yyyy HH:mm',$null)
        $this.LeaveDate   = [datetime]::ParseExact("$($TraceUser.'Leaving Date') 23:59",'dd/MM/yyyy HH:mm',$null)
    }
}

如果我用AD用户作为参数来实例化一个对象 就会使用第一个构造函数 但如果我用数组来实例化,就会使用第二个构造函数。

这似乎行不通,我在网上搜索到的只是如何通过使用不同数量的参数来重载。没有关于基于类型的重载。

这可能吗?

EDIT:再给大家讲讲背景。ArcSet 下面猜对了我的错误。我看到。

Cannot find an overload for "new" and the argument count: "1".

传递给第一个构造函数的$ADUser是通过运行Get -ADUser获得的. 传递给第二个构造函数的$TraceUser来自一个Import-CSV。

当我实例化一个User类的对象时,我将用一个来自Get-ADUser的AD User来调用它,在这种情况下,我希望第一个构造函数运行,或者我将用一个来自Import-CSV的System.Array来调用它,在这种情况下,我希望第二个构造函数运行。

实际上,我是在ForEach循环中实例化这些,但我认为这与这里无关。下面是我如何创建这些的例子。

$oneADUser      = Get-ADUser -Filter * -SearchBase $OU
$oneTraceUser   = Import-CSV somefile.csv
$NewADUsers     = @()
$NewTraceUsers  = @()
$NewADUsers    += [User]::new($oneADUser)    # This should use the first constructor
$NewTraceUsers += [User]::new($oneTraceUser) # This should use the second constructor

我这样做对吗?

powershell class types constructor overloading
1个回答
1
投票

我想你可能得到的错误是

Cannot find an overload for "User" and the argument count: "{Some Number Here like 85}"

这是因为它将你传递的数组视为参数数组。

New-Object User -ArgumentList (Get-ADUser -Filter * | select -First 3)

这将导致失败,并出现以下信息

Cannot find an overload for "User" and the argument count: "3"**

如何解决这个问题,就是把一个 , 之前

New-Object User -ArgumentList (,(Get-ADUser -Filter * | select -First 3))

您也可以使用 ::New()

[User]::new((Get-ADUser -Filter * | select -First 3))

0
投票

好了,我想明白了。谢谢大家的帮助。

为了让它工作,我必须在把$oneTraceUser传给构造函数之前,先把$oneTraceUser转换为一个System.Array。最终的工作代码是这样的。

class User {
    [string]$GivenName
    [string]$Surname
    [string]$DisplayName
    [string]$Company
    [string]$PayrollNo
    [string]$Email
    [DateTime]$StartDate
    [DateTime]$LeaveDate

    User([Microsoft.ActiveDirectory.Management.ADAccount]$ADUser) {
        $this.GivenName   = $ADUser.GivenName
        $this.Surname     = $ADUser.Surname
        $this.DisplayName = $ADUser.Name
        $this.PayrollNo   = $ADUser.EmployeeID
        $this.Email       = $ADUser.EmailAddress
        #$this.LeaveDate  = $ADUser.AccountExpires
    }

    User([System.Array]$TraceUser) {
        $this.GivenName   = $TraceUser.'First Name'
        $this.Surname     = $TraceUser.Surname
        $this.DisplayName = "$($TraceUser.'First Name') $($TraceUser.Surname)"
        $this.Company     = $TraceUser.'Payroll Company'
        $this.PayrollNo   = $TraceUser.'Payroll No'
        $this.Email       = $TraceUser.'E-Mail'
        $this.StartDate   = [datetime]::ParseExact("$($TraceUser.'Start Date') 23:59",'dd/MM/yyyy HH:mm',$null)
        $this.LeaveDate   = [datetime]::ParseExact("$($TraceUser.'Leaving Date') 23:59",'dd/MM/yyyy HH:mm',$null)
    }
}

$NewADUsers = New-Object -TypeName "System.Collections.ArrayList"
$NewTraceUsers = New-Object -TypeName "System.Collections.ArrayList"
$TraceData = Import-CSV $TraceCSV
$ADUsers = Get-ADUser -Filter * -SearchBase $OU -Properties EmployeeID
$TraceUsers = $TraceData | Where-Object 'Payroll Company' -eq $OU.DestinationIndicator
forEach($oneADUser in $ADUsers) {
    $NewADUser = [User]::new($oneADUser)
    forEach($oneTraceUser in $TraceUsers) {
        $NewTraceUser = [User]::new([System.Array]$oneTraceUser)
        $Result = Compare-Users $NewADUser $NewTraceUser
        Write-Output $Result
    }
}

我现在有了一个User类,根据传递给它的变量类型,它将运行两个类似的构造函数中的一个,从AD或CSV文件中导入数据,并且可以继续使用这个类在通用用户之间进行比较。

© www.soinside.com 2019 - 2024. All rights reserved.