How can one create an object that when its operators, such as:
operator > (Object obj1, Object obj2)
operator < (Object obj1, 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:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With