Powershell 您能否实现一个动态创建的PSObject,从而使相等和比较有效?
我一直在通过向PSObject动态添加方法来实现临时类型 我希望能够使用“-eq”“-lt”和“-gt”运算符比较我的对象的两个实例(我假设这需要我实现像icomparable和IEquatible这样的接口) 这可能吗?(我的想法可能不是因为这些事情通常发生在类型级别上,我的临时“类型”都是相同的类型)Powershell 您能否实现一个动态创建的PSObject,从而使相等和比较有效?,powershell,operators,metaprogramming,Powershell,Operators,Metaprogramming,我一直在通过向PSObject动态添加方法来实现临时类型 我希望能够使用“-eq”“-lt”和“-gt”运算符比较我的对象的两个实例(我假设这需要我实现像icomparable和IEquatible这样的接口) 这可能吗?(我的想法可能不是因为这些事情通常发生在类型级别上,我的临时“类型”都是相同的类型) 如果没有,我还能做些什么(除了使用c#)吗?我认为您不能将接口附加到正在创建的psobject上。但是,您可以在实现适当接口并重写适当方法的C#类中创建类型。您甚至可以在here字符串中定义此
如果没有,我还能做些什么(除了使用c#)吗?我认为您不能将接口附加到正在创建的psobject上。但是,您可以在实现适当接口并重写适当方法的C#类中创建类型。您甚至可以在here字符串中定义此类型,并使用Add type对其进行编译并将其加载到PowerShell中。然后您只需创建该类型而不是psobject。它应该具有您感兴趣的所有相关属性以及进行比较/相等的能力 根据我的评论,这里是如何在脚本中实现这一点,而执行过程中的麻烦最小,即只要在更改C代码时更改typename变量即可
我认为您无法将接口附加到正在创建的psobject上。但是,您可以在实现适当接口并重写适当方法的C#类中创建类型。您甚至可以在here字符串中定义此类型,并使用Add type对其进行编译并将其加载到PowerShell中。然后您只需创建该类型而不是psobject。它应该具有您感兴趣的所有相关属性以及进行比较/相等的能力 根据我的评论,这里是如何在脚本中实现这一点,而执行过程中的麻烦最小,即只要在更改C代码时更改typename变量即可
正如我在问题中提到的,我正在寻找一种不使用C#和Add Type的方法。我的理由是,我不希望我的整个脚本能够从Powershell中轻松调试,我希望能够在不必重新启动Powershell会话的情况下进行更改。对不起,我肯定错过了关于不使用Add Type的部分。“解决”这个问题的一种方法是参数化类型名,并在C#更改时在执行之间更改它。否则,您可以测试类型是否已经存在,并跳过添加类型调用。我真的不喜欢c#被集成的方式中的不灵活,但这是一个很好的答案。尽管如此,当我在调试脚本的c#部分时不得不不断更改类型名称时,我也很恼火,但当类型名称被参数化时,至少痛苦是显而易见的最小化。:-)正如我在问题中提到的,我正在寻找一种不使用C#和Add Type的方法。我的理由是,我不希望我的整个脚本能够从Powershell中轻松调试,我希望能够在不必重新启动Powershell会话的情况下进行更改。对不起,我肯定错过了关于不使用Add Type的部分。“解决”这个问题的一种方法是参数化类型名,并在C#更改时在执行之间更改它。否则,您可以测试类型是否已经存在,并跳过添加类型调用。我真的不喜欢c#被集成的方式中的不灵活,但这是一个很好的答案。尽管如此,当我在调试脚本的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