Visual Studio在未引用库时选择错误的构造函数?

Sco*_*ott 5 c# .net-4.0 visual-studio-2010

我正在使用Visual Studio 2010和两个项目.

一个包含引用Microsoft的Exchange.WebServices dll(ver1.2)的项目,用于访问ExchangeServices.我创建了一个类,其中包含一些辅助方法和包装器,以便在连接到Exchange服务器(通过ExchangeService API)时执行各种任务.ExchangeService构造函数可以接受ExchangeVersion的枚举,以指定服务器版本信息.所以我在班上创建了两个构造函数.

public class ExchangeConnector(string ver)
{
    // Property assignments
}

public class ExchangeConnector(ExchangeVersion ver)
    :this(ver.toString()) //Using(or not using) "this", doesn't seem to matter...
{ }
Run Code Online (Sandbox Code Playgroud)

我创建了接受字符串参数的构造函数,因此其他项目不一定需要添加Exchange.WebServices库.

但后来我遇到了一个未经预见的问题.

当我在第二个项目中创建一个ExchangeConnector实例("Exchange2007_SP1")(不包含对Exchange.WebServices dll的引用)时,Intellisense没有选择正确的构造函数,也没有显示任何预编译错误.但是,当我强制构建时,我收到以下错误:

Error: The type 'Microsoft.Exchange.WebServices.Data.ExchangeVersion' is defined
in an assembly that is not referenced. You must add a reference to assembly
'Microsoft.Exchange.WebServices, Version=14.0.0.0, Culture=neutral, 
PublicKeyToken=31bf3856ad364e35'.
Run Code Online (Sandbox Code Playgroud)

我甚至没有使用带有ExchangeVersion枚举引用的构造函数,但它需要我引用它?

如果我用ExchangeVersion枚举注释掉构造函数,那么一切都会编译,工作,没有运行时错误.或者如果我修改了重载构造函数,那么Intellisense不可能混淆两者,例如:

public class ExchangeConnector(string url, ExchangeVersion ver)
{ 
  // Property assignments
}
Run Code Online (Sandbox Code Playgroud)

当我调用ExchangeConnector("Exchange2007_SP1")时,代码编译并正常工作.没有运行时错误.

几乎就像VS无法解析正确使用哪个构造函数一样.现在我知道我可以添加对第二个项目的引用并完成它,但我很好奇为什么VS这样做.有任何想法吗?

Sco*_*ott 6

在Scott(另一个)的灵感和CodeCaster提供的链接之后,我想我终于找到了答案.

它作为C#语言规范(Visual Studio .Net 2003 Edition)的一部分.

第10.10节的实例构造函数中:

形式base(argument-listopt)的实例构造函数初始值设定项会导致调用直接基类的实例构造函数.使用参数列表和第7.4.2节的重载决策规则选择该构造函数.候选实例构造函数集包含直接基类中包含的所有可访问实例构造函数(包括任何默认构造函数,如第10.10.4节中所定义).如果此set为空,或者无法识别单个最佳实例构造函数,则会发生编译时错误.

进一步深入定义......

第7.4.2节中过载分辨率:

一旦确定了候选函数成员和参数列表,最佳函数成员的选择在所有情况下都是相同的:

  • 给定一组适用的候选函数成员,找到该集合中的最佳函数成员.
  • 如果集合只包含一个函数成员,那么该函数成员是最好的函数成员.
  • 否则,最好的函数成员是一个函数成员,它比给定参数列表中的所有其他函数成员更好,只要使用第7.4.2.2节中的规则将每个函数成员与所有其他函数成员进行比较.
  • 如果没有一个函数成员优于所有其他函数成员,则函数成员调用不明确并且发生编译时错误.

甚至更进一步......

第7.4.2.2节更好的功能成员[3]

[3] [http://msdn.microsoft.com/en-us/library/aa691338(V = vs.71)的.aspx]

给定一个参数列表A,其中包含一组参数类型{A1,A2,...,AN}和两个适用的函数成员MP和MQ,参数类型为{P1,P2,...,PN}和{Q1,Q2, ...,QN},MP被定义为比MQ更好的函数成员if

  • 对于每个参数,从AX到PX的隐式转换并不比从AX到QX的隐式转换更糟糕
  • 对于至少一个参数,从AX到PX的转换优于从AX到QX的转换.

执行此评估时,如果MP或MQ适用于其扩展形式,则PX或QX引用参数列表的扩展形式中的参数.

总结如下:

必须通过隐式转换来评估具有相同数量参数的构造函数,以确定哪个函数成员(构造函数)会更好.

因此,为什么我需要添加对第二个项目的引用,以便编译器可以确定哪个构造函数更好.

如果构造函数没有相同数量的参数,则不需要进行评估,并且编译器不需要对第二个项目的引用.