An interesting and weird thing I noticed writing PowerShell classes lines:
class A {
    [object] WhereObject(){
        return @(1,2) | Where-Object {$_ -gt 2}
    }
    [object] Where(){
        return @(1,2).Where( {$_ -gt 2})
    }
}
$a = new-object A
$a.WhereObject() # Throw exception Index was out of range. Must be non-negative and less than the size of the collection.
$a.Where() # Works well
It looks like it is by design. Why does it work so?
Workaround
Function which explicitly convert "empty" value to $null:
function Get-NullIfEmpty {
   param(
       [Parameter(ValueFromPipeline=$true)][array] $CollectionOrEmtpy
   )
   begin { $output = $null }
   process
   {
      if($output -eq $null -and $CollectionOrEmtpy -ne $null){
          $output = @()
      }
      foreach ($element in $CollectionOrEmtpy)
      {
          $output += $element
      }
   }
   end { return $output }
}
In this case, the method will look like:
[object] WhereObject() {
   return @(1,2) | Where-Object {$_ -gt 2} | Get-NullIfEmpty
}
I tried to return an empty array from the class method, but it is also tricky because for a regular function an empty array means "nothing" as well. If you have a call chain like method1 -> function -> method2 - method1 throw the same exception. Because the function converts an empty array to nothing.
So converting to $null is optimal in my case :)