Domanda

Quando utilizzo un altro oggetto in .NET-Framework in C# posso salvare molta digitazione utilizzando la direttiva usando.

using FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It;

...


  var blurb = new Thingamabob();

...

Quindi c'è un modo in PowerShell per fare qualcosa di simile? Accedo a molti oggetti .NET e non sono felice di dover digitare

 $blurb = new-object FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob;

tutto il tempo.

È stato utile?

Soluzione

PowerShell 5.0 (incluso in WMF5 o Windows 10 e in su), aggiunge il using namespace Costruire alla lingua. Puoi usarlo nella tua sceneggiatura in questo modo:

#Require -Version 5.0
using namespace FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It
$blurb = [Thingamabob]::new()

(Il #Require L'istruzione sulla prima riga non è necessaria per l'uso using namespace, ma impedirà allo script di funzionare in PS 4.0 e sotto dove using namespace è un errore di sintassi.)

Altri suggerimenti

Non c'è davvero nulla a livello dello spazio dei nomi del genere. Assegno spesso i tipi comunemente usati alle variabili e quindi a istancio:

$thingtype = [FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob];
$blurb = New-Object $thingtype.FullName

Probabilmente non ne vale la pena se il tipo non verrà utilizzato ripetutamente, ma credo che sia il meglio che puoi fare.

Dai un'occhiata a questo post sul blog di un paio di anni fa: http://blogs.msdn.com/richardb/archive/2007/02/21/add-types-ps1 poor-man-s-using-for-powershell.aspx

Qui è add-types.ps1, estratto da quell'articolo:

param(
    [string] $assemblyName = $(throw 'assemblyName is required'),
    [object] $object
)

process {
    if ($_) {
        $object = $_
    }

    if (! $object) {
        throw 'must pass an -object parameter or pipe one in'
    }

    # load the required dll
    $assembly = [System.Reflection.Assembly]::LoadWithPartialName($assemblyName)

    # add each type as a member property
    $assembly.GetTypes() | 
    where {$_.ispublic -and !$_.IsSubclassOf( [Exception] ) -and $_.name -notmatch "event"} | 
    foreach { 
        # avoid error messages in case it already exists
        if (! ($object | get-member $_.name)) {
            add-member noteproperty $_.name $_ -inputobject $object
        }
    }
}

E, per usarlo:

RICBERG470> $tfs | add-types "Microsoft.TeamFoundation.VersionControl.Client"
RICBERG470> $itemSpec = new-object $tfs.itemspec("$/foo", $tfs.RecursionType::none)

Fondamentalmente quello che faccio è strisciare l'assemblaggio per tipi non banali, quindi scrivere un "costruttore" che utilizza add-member aggiungendoli (in modo strutturato) agli oggetti a cui tengo.

Vedi anche questo post di follow -up: http://richardberg.net/blog/?p=38

Questo è solo uno scherzo, scherzo ...

$fullnames = New-Object ( [System.Collections.Generic.List``1].MakeGenericType( [String]) );

function using ( $name ) { 
foreach ( $type in [Reflection.Assembly]::LoadWithPartialName($name).GetTypes() )
    {
        $fullnames.Add($type.fullname);
    }
}

function new ( $name ) {
    $fullname = $fullnames -like "*.$name";
    return , (New-Object $fullname[0]);
}

using System.Windows.Forms
using FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It
$a = new button
$b = new Thingamabob

Ecco un codice che funziona in PowerShell 2.0 per aggiungere alias di tipo. Ma il problema è che non è scoperto. Con un po 'di lavoro extra potresti "non fare" gli spazi dei nomi, ma questo dovrebbe farti iniziare bene.

##############################################################################
#.SYNOPSIS
# Add a type accelerator to the current session.
#
#.DESCRIPTION
# The Add-TypeAccelerator function allows you to add a simple type accelerator
# (like [regex]) for a longer type (like [System.Text.RegularExpressions.Regex]).
#
#.PARAMETER Name
# The short form accelerator should be just the name you want to use (without
# square brackets).
#
#.PARAMETER Type
# The type you want the accelerator to accelerate.
#
#.PARAMETER Force
# Overwrites any existing type alias.
#
#.EXAMPLE
# Add-TypeAccelerator List "System.Collections.Generic.List``1"
# $MyList = New-Object List[String]
##############################################################################
function Add-TypeAccelerator {

    [CmdletBinding()]
    param(

        [Parameter(Position=1,Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
        [String[]]$Name,

        [Parameter(Position=2,Mandatory=$true,ValueFromPipeline=$true)]
        [Type]$Type,

        [Parameter()]
        [Switch]$Force

    )

    process {

        $TypeAccelerators = [Type]::GetType('System.Management.Automation.TypeAccelerators')

        foreach ($a in $Name) {
            if ( $TypeAccelerators::Get.ContainsKey($a) ) {
                if ( $Force ) {
                    $TypeAccelerators::Remove($a) | Out-Null
                    $TypeAccelerators::Add($a,$Type)
                }
                elseif ( $Type -ne $TypeAccelerators::Get[$a] ) {
                    Write-Error "$a is already mapped to $($TypeAccelerators::Get[$a])"
                }
            }
            else {
                $TypeAccelerators::Add($a, $Type)
            }
        }

    }

}

Se devi solo creare un'istanza del tuo tipo, puoi archiviare il nome dello spazio dei nomi lungo in una stringa:

$st = "System.Text"
$sb = New-Object "$st.StringBuilder"

Non è potente come il using Direttiva in C#, ma almeno è molto facile da usare.

Grazie a tutti per il tuo contributo. Ho segnato il contributo di Richard Berg come risposta, perché assomiglia molto a quello che sto cercando.

Tutte le tue risposte mi hanno portato in pista che sembra più promettente: in Il suo post sul blog Keith Dahlby propone un comando di tipo get che consente una facile consursione di tipi per metodi generici.

Penso che non ci sia motivo di Exeting questo per cercare anche attraverso un percorso predefinito di assiemi per un tipo.

Disclaimer: non l'ho ancora costruito - ancora ...

Ecco come si potrebbe usarlo:

$path = (System.Collections.Generic, FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It)

$type = get-type -Path $path List Thingamabob
$obj = new-object $type
$obj.GetType()

Ciò comporterebbe un bel elenco generico di ThingAmabob. Naturalmente avrei concluso tutto senza la definizione del percorso in un'altra funzione di utilità. Il tipo di getto esteso includerebbe un passaggio per risolvere un dato tipo di percorso.

#Requires -Version 5
using namespace System.Management.Automation.Host
#using module

Mi rendo conto che questo è un vecchio post, ma stavo cercando la stessa cosa e mi sono imbattuto in questo: http://weblogs.asp.net/adweigert/powershell-adding-the-using-statement

Modifica: suppongo che dovrei specificare che ti consente di utilizzare la sintassi familiare di ...

using ($x = $y) { ... }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top