您可以实现动态创建的 PSObject 以便进行相等和比较吗?

发布于 2024-09-16 00:12:28 字数 214 浏览 5 评论 0原文

我一直通过向 PSObjects 动态添加方法来实现临时类型

我希望能够使用“-eq”“-lt”和“-gt”运算符来比较对象的两个实例(我认为这需要我实现接口像 IComparible 和 IEquatible)

这种事情可能吗? (我想也许不是,因为这些事情通常发生在类型级别,而我的临时“类型”都是相同的类型)

如果不是,我还能做些什么(除了使用 c# 之外)?

I have been implementing makeshift types by dynamically adding methods to PSObjects

I want to be able to compare two instances of my objects using the "-eq" "-lt" and "-gt" operators (I assume this would require me to implement interfaces like IComparible, and IEquatible)

Is this sort of thing possible? (I'm thinking perhaps not as these things usually happen on the type level and my makeshift "types" are all the same type)

If not is there something else I can do (other than using c#)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浪菊怪哟 2024-09-23 00:12:28

我认为您无法将接口附加到您正在创建的 psobject 上。但是,您可以在实现适当接口并重写适当方法的 C# 类中创建类型。您甚至可以在此处的字符串中定义此类型,然后使用 Add-Type 对其进行编译并将其加载到 PowerShell 中。然后您只需创建该类型而不是 psobject。它应该具有您感兴趣的所有相关属性以及进行比较/相等的能力。

根据我的评论,以下是如何在脚本中执行此操作,同时在执行期间将头痛最小化,即每当更改 C# 代码时,您只需要更改 typename 变量。

$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

I don't think you can tack on the interfaces to the psobject you're creating. However, you can create your type in a C# class that implements the appropriate interfaces and overrides the appropriate methods. You can even define this type in a here string and use Add-Type to compile it and load it into PowerShell. Then you just create that type instead of psobject. It should have all the relevant properties you're interested as well as the ability to do comparison/equality.

Per my comment, here is how to do this in your script with minimal headache bewteen executions i.e. you only need to change the typename variable whenever you change the C# code.

$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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文