Bug when overriding ToString? PowerShell5 classes

class Yay {
    [string] ToString() { # Same case as System.Object.ToString()
        return "I am Yay"

class Nay {
    [string] TOSTRING() { # Different case
        return "I am Nay"

$yay = [Yay]::new()
[string] $yay

$nay = [Nay]::new()
[string] $nay

The above will give you:
I am Yay
I am Yay
I am Nay

This must certainly be a bug? Expected result would be that the fourth line also said the same as the third, “I am Nay”.

What is going on here? There is some kind of weird case sensitivity going on when defining methods?

I’m not sure if I’d call that a bug in PowerShell or not. Strictly speaking, calling $nay.ToString() would wind up calling the base [Object] ToString(), if you had that equivalent code in C#, because TOSTRING() is different. PowerShell has always tried to be a little more lenient about that sort of thing, and it sees that there is a method on the object (not parent classes) that differs only by case, so it calls that method. It would appear that whatever code runs when you just cast something to [string] doesn’t have that same behavior; it just goes straight for ToString() and doesn’t look for close matches.

You could certainly report this on UserVoice and see where it goes. Could be something that MS will treat as a bug, and fix in a future release.

I’ve tried some variants in C# and in C# it makes sense:

  • You would have to explicitly set the “override” keyword to override.
  • You wouldn’t be able to call a function with wrong case.
  • You can’t cast an object to something it isn’t based on (or what ever actually happens in PS when you say “[string] $nay”)

I actually can’t tell if this PS example is a bug or not myself. But I would without a doubt consider it unwanted behavior in the language.

I sadly find this to be one of the many errors in PS. It’s not a precise language and it tries to “help” you with too much :frowning: