4

我正在使用TaskBar在命名空间中定义的方法Microsoft.WindowsAPICodePack.Taskbar。具体来说,我将专注于SetProgressState这个问题。

这是我在询问 的定义时得到的元定义SetProgressState

namespace Microsoft.WindowsAPICodePack.Taskbar
{
    public class TaskbarManager
    {
        public void SetProgressState(TaskbarProgressBarState state);
        public void SetProgressState(TaskbarProgressBarState state, IntPtr windowHandle);
        public void SetProgressState(TaskbarProgressBarState state, System.Windows.Window window);
    }
}

显然,我省略了该类的大部分定义,只是为了突出一个方法的重载。

到目前为止,我一直在使用单参数重载并且没有遇到任何问题。但是,今天我尝试使用接受 anIntPtr作为其第二个参数的双参数重载。

当我这样做时,我在构建期间开始收到此错误:

“System.Windows.Window”类型是在未引用的程序集中定义的。您必须添加对程序集 'PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' 的引用

所以我的问题是为什么我在使用单参数重载时没有收到错误,但在引用其他参数时我确实收到了错误(以及错误的)?

编辑(添加子问题):

我还尝试了以下方法,但没有任何区别:

SetProgressState(myState, (IntPtr) myWindowHandle);

我认为通过显式转换,我可以避免编译器在实现适当的重载时混淆,但事实并非如此。

4

2 回答 2

2

根据MSDN page on Overload Resolution,编译器将首先选择潜在的候选者

这些上下文中的每一个都以自己独特的方式定义候选函数成员集和参数列表

然后,选择最佳目标:

如果该集合仅包含一个函数成员,则该函数成员是最佳函数成员。

我的理解是,当您使用 1 个参数调用它时,编译器甚至不会考虑 2 个参数方法。但是,当您使用 2 参数版本时,它需要有关参数类型的信息。在这种情况下,它需要知道什么System.Windows.Window才能确定您要调用哪个重载。

例子

想象一下,您在不同的类库中有 2 个类

class Foo
{

}

class Bar : Foo
{

}

和另一个库中的 4 个方法

static void Do()
{

}

static void Do(Foo foo)
{

}

static void Do(Bar bar)
{

}

static Foo Get()
{
    return new Bar();
}

您引用了方法库和包含的库Foo,但没有引用包含的库Bar

然后,在您的应用程序中,您Foo从方法库中获得一个类型的对象(它也可能是一个Bar,但您不知道)。编译器应该如何Do()用参数解决最终的调用?

它不能,除非它也有 Bar 的类型信息。


至于您的子问题,这是上述结果加上演员不一定强制选择重载的事实。让我们暂时想象System.Windows.Window一下IntPtr。将参数强制转换为IntPtr根本无法帮助编译器解决重载问题(参见上面的示例)。

由于类型信息不存在,编译器会发出错误,因为它无法确定。老实说,对于编译器来说,这是一个特性。

于 2013-06-26T14:15:00.007 回答
1

为了清楚起见,我将在这里扩展我的评论。您的项目找不到 System.Windows.Window。当我说你需要输入时,我在评论中说错了:

using System.Windows;

到文件。

相反,该项目需要引用 System.Windows。您想要的参考在错误消息中提供给您:PresentationFramework。您还需要包含 PresentationCore(会弹出一个类似的错误,告诉您添加对 PresentationCore 的引用)。

“System.Windows.Window”类型是在未引用的程序集中定义的。您必须添加对程序集的引用' PresentationFramework , Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

于 2013-06-26T15:37:58.653 回答