Powershell and overriden comparision operators
How can one create an object that when its operators, such as:
operator > (Object obj1, Object obj2)
operator < (Object 开发者_如何学Goobj1, Object obj2)
, are overridden PowerShell utilizes these operators?
Such that:
where-object { $CustomObject -gt 12 }
would call:
public static bool operator > (Object object1, Object object2)
Is it possible?
To clarify:
- The object exists within a .NET assembly
- The object has overridden comparision operators
- PowerShell does not seem to honor these operators
PowerShell is using the IComparable interface to compare objects. At least, this is what the following little experiment shows:
$src = @'
using System;
namespace Acme
{
public class Foo : IComparable
{
public Foo(int value)
{
this.Value = value;
}
public int Value { get; private set; }
public static bool operator >(Foo foo1, Foo foo2)
{
Console.WriteLine("In operator >");
return (foo1.Value > foo2.Value);
}
public static bool operator <(Foo foo1, Foo foo2)
{
Console.WriteLine("In operator <");
return (foo1.Value < foo2.Value);
}
public int CompareTo(object obj)
{
Console.WriteLine("In CompareTo");
if (obj == null) return 1;
Foo foo2 = obj as Foo;
if (foo2 == null) throw new ArgumentException("Not type Foo","obj");
if (this.Value == foo2.Value)
{
return 0;
}
else if (this.Value > foo2.Value)
{
return 1;
}
else
{
return -1;
}
}
}
}
'@
Add-Type -TypeDefinition $src -Language CSharpVersion3
$foo1 = new-object Acme.Foo 4
$foo2 = new-object Acme.Foo 8
$foo1 -gt $foo2
In CompareTo
False
You can overload an operator in C#
If you are using the operator in powershell, the c# overloaded operator will be used
// overloading + operator
public static Nimber operator +(Nimber left, Nimber right)
{
var length = (left.List.Count > right.List.Count) ? left.List.Count : right.List.Count;
var list = new int[length];
for (int i = 0; i < left.List.Count; i++)
{
list[i] = left.List[i];
}
for (int i = 0; i < right.List.Count; i++)
{
list[i] += right.List[i];
}
return new Nimber(list);
}
posershell use
Add-Type -Path $TheAssemblyPath
$n1 = New-Object nim.nimber (1,2,4)
$n2 = New-Object nim.nimber (10,20,40,50)
"n1=$n1 and n2=$n2"
$n3 = $n1 + $n2
"n3=$n3"
and the output is
n1=1, 2, 4 and n2=10, 20, 40, 50
n3=11, 22, 44, 50
In order to compare two instances of a custom PowerShell class with the -lt
, -le
, -ge
and -gt
operators, your class should implement the System.IComparable
interface, and you can do that in a plain PowerShell (that is, you don't need to use AddType
):
Class MyClass : System.IComparable
{
[int] $Value
MyClass([int] $v)
{
$this.Value = $v
}
[int] CompareTo($that)
{
return $this.Value - $that.Value
}
}
$instance1 = [MyClass]::new(1)
$instance2 = [MyClass]::new(2)
Write-Output ($instance1 -lt $instance2)
#Output: True
Write-Output ($instance1 -le $instance2)
#Output: True
Write-Output ($instance1 -ge $instance2)
#Output: False
Write-Output ($instance1 -gt $instance2)
#Output: False
BTW I faced problems when comparing subclasses: see PowerShell IComparable with subclasses
I do not believe you can do operator overloading in Powershell.
You cannot do operator overloading in PowerShell, but I believe the way you've declared it will work as PowerShell should obey the operator overloading of .NET. When this does not work what you are often seeing is different objects on each side, i.e. a [int] -gt [string]. You can always try explictly casting both of the objects before a comparison.
Hope this helps
精彩评论