Можете ли вы реализовать динамически созданный объект PSObject таким образом, чтобы обеспечить равенство и сравнение? - PullRequest
1 голос
/ 26 августа 2010

Я реализовывал временные типы, динамически добавляя методы в PSObjects

Я хочу иметь возможность сравнивать два экземпляра моих объектов, используя операторы "-eq", "-lt" и "-gt" (я полагаю, что для этого потребуется реализовать интерфейсы, такие как IComparible и IEquatible)

Возможна ли такая вещь? (Я думаю, возможно, нет, поскольку эти вещи обычно происходят на уровне типов, и мои временные "типы" все одного типа)

Если нет, могу ли я что-то еще сделать (кроме использования c #)?

1 Ответ

4 голосов
/ 26 августа 2010

Не думаю, что вы можете привязать интерфейсы к создаваемому псобъекту. Однако вы можете создать свой тип в классе C #, который реализует соответствующие интерфейсы и переопределяет соответствующие методы. Вы даже можете определить этот тип в строке здесь и использовать Add-Type для его компиляции и загрузки в PowerShell. Затем вы просто создаете этот тип вместо psobject. Он должен иметь все соответствующие свойства, которые вас интересуют, а также умение сравнивать / сравнивать.

В соответствии с моим комментарием, вот как это сделать в вашем скрипте с минимальной головной болью при выполнении, т. Е. Вам нужно изменять переменную typename только при изменении кода C #.

$foo = "Foo"

$src = @"
using System;
public class $foo : IComparable {
    public string Name {get; set;}
    public int Age {get; set;}
    public int CompareTo(object obj)
    {
        $foo other = obj as $foo;
        if (other == null) 
            throw new ArgumentException("arg must be type $foo or not null");
        return Age.CompareTo(other.Age);
    }

    public override bool Equals(object obj)
    {
        if (obj == null) return false;
        if (Object.ReferenceEquals(this, obj)) return true;

        $foo other = obj as $foo;
        if (other == null) 
            throw new ArgumentException("arg must be type $foo or not null");
        return Age.Equals(other.Age) && Name.Equals(other.Name);    
    }

    public override int GetHashCode()
    {
        return Age.GetHashCode() ^ Name.GetHashCode();
    }

    public override string ToString()
    {
        return String.Format("Name: {0}, age: {1}", Name, Age);
    }
}
"@

if (![Type]::GetType($foo))
{
    Add-Type -TypeDefinition $src -Language CSharpVersion3
}

$foo1 = New-Object $foo
$foo1.Age = 47
$foo1.Name = 'Keith'
$foo1


$foo2 = New-Object $foo
$foo2.Age = 45
$foo2.Name = 'John'
$foo2

$foo2 -gt $foo1
...