WTF Method overloads resolution in PowerShell

I have got another WTF!

It seems that PowerShell method overload resolution system is not consistent with C#

Let’s compare

C#

    class Program
    {
        static void Main(string[] args)
        {
            MyClass.MyMethod(false, DateTime.Now);
        }
    }

    public static class MyClass
    {
        public static void MyMethod(object obj, DateTime dateTime)
        {
            Console.WriteLine("MyClass.MyMethod(object obj, DateTime dateTime)");
        }

        public static void MyMethod(bool b, string str)
        {
            Console.WriteLine("MyClass.MyMethod(bool b, string str)");
        }
    }

vs

PowerShell

Add-Type `
@"
    using System;

    public static class MyClass
    {
        public static void MyMethod(object obj, DateTime dateTime)
        {
            Console.WriteLine("MyClass.MyMethod(object obj, DateTime dateTime)");
        }

        public static void MyMethod(bool b, string str)
        {
            Console.WriteLine("MyClass.MyMethod(bool b, string str)");
        }
    }
"@

[MyClass]::MyMethod($false, [DateTime]::Now)

C# will return

MyClass.MyMethod(object obj, DateTime dateTime)

How we expected

But PowerShell will return

MyClass.MyMethod(bool b, string str)

If we want to have the correct method called we have to be more explicit about overload we want to call

[MyClass]::MyMethod([object] $false, [DateTime]::Now)

I found this issue very annoying

I had the following NUnit-like test in PoshUnit which uses real NUnit behind the scenes

$Assert::That($false, $Is::False)

And this test failed!!!

The reason is absolutely the same

Assert.That has a lot of overloads.
With my code I expected

public static void That(object actual, IResolveConstraint expression)

but actually the following one was called

public static void That(bool condition, string message)

It is extremely annoying.

I think it is a bug in PowerShell, not a feature

UPD:

The code above was tested in PowerShell 3

In PowerShell 2 the situation is even worse. I could not find a way to call a proper overload

Even this one does not work

[MyClass]::MyMethod([object] $false, [DateTime] ([DateTime]::Now))

UPD:

Raised a question http://stackoverflow.com/questions/13084176/powershell-method-overload-resolution-bug

UPD:
Raised bug for Microsoft
https://connect.microsoft.com/PowerShell/feedback/details/768901/powershell-method-overload-resolution

Advertisements

About mnaoumov

Senior .NET Developer in Readify
This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s