我正在使用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...
{ }
我创建了接受字符串参数的构造函数,因此其他项目不一定需要添加Exchange.WebServices库。
但后来我遇到了一个未经预见的问题。
当我在第二个项目(不包含对Exchange.WebServices dll的引用)中创建ExchangeConnector实例(" Exchange2007_SP1")时,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'.
我甚至没有使用带有ExchangeVersion枚举引用的构造函数,但是它需要我引用它?
如果我用ExchangeVersion枚举注释掉构造函数,那么一切都编译,工作,没有运行时错误。 要么 如果我修改了重载构造函数,那么Intellisense可能会混淆两者,例如:
public class ExchangeConnector(string url, ExchangeVersion ver)
{
// Property assignments
}
当我调用ExchangeConnector(" Exchange2007_SP1")时,代码编译并正常工作。没有运行时错误。
几乎就好像VS无法解析正确使用哪个构造函数。现在我知道我可以添加对第二个项目的引用并完成它,但我很好奇为什么VS这样做。有什么想法吗?
答案 0 :(得分:5)
经过Scott(另一个)的灵感和CodeCaster提供的链接,我想我终于找到了答案。
它是C#语言规范(Visual Studio .Net 2003 Edition)的一部分。
在Section 10.10 Instance Constructors中:
表单base(argument-listopt)的实例构造函数初始值设定项会导致调用直接基类的实例构造函数。使用参数列表和第7.4.2节的重载决策规则选择该构造函数。候选实例构造函数集包含直接基类中包含的所有可访问实例构造函数(包括任何默认构造函数,如第10.10.4节中所定义)。如果此set为空,或者无法识别单个最佳实例构造函数,则会发生编译时错误。
进一步深入定义...
在Section 7.4.2 Overload resolution中:
一旦确定了候选函数成员和参数列表,最佳函数成员的选择在所有情况下都是相同的:
- 给定一组适用的候选函数成员,找到该集合中最好的函数成员。
- 如果集合只包含一个函数成员,那么该函数成员是最好的函数成员。
- 否则,最佳函数成员是一个函数成员,它比给定参数列表中的所有其他函数成员更好,前提是使用第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更好的函数成员
- 对于每个参数,从AX到PX的隐式转换并不比从AX到QX的隐式转换更差,并且
- 对于至少一个参数,从AX到PX的转换优于从AX到QX的转换。
执行此评估时,如果MP或MQ适用于其扩展形式,则PX或QX引用参数列表的展开形式的参数。
总结如下:
必须通过隐式转换来评估具有相同数量参数的构造函数,以确定哪个函数成员(构造函数)会更好。
因此我需要添加对第二个项目的引用,以便编译器可以确定哪个构造函数更好。
如果构造函数没有相同数量的参数,则不需要进行评估,编译器也不需要对第二个项目的引用。
答案 1 :(得分:3)
对我来说,如果你的项目引用了另一个带有重载构造函数的项目,其中一个构造函数接受了一个引用的库,那么即使你没有使用那个特定的构造函数,你的调用项目也需要编译引用。编译器是否需要该引用来决定使用哪个构造函数?也许我错过了一些东西,但对我来说,它的工作正常是合乎逻辑的。