我正在使用VS2012 v.11.0.61030.00 Update 4.我使用C#。我有一个带有两个构造函数的类:一个用于正常使用测试。
using ServiceLayer;
namespace PresentationLayer
{
public class Orchestrator
{
private NumberService svc;
public Orchestrator(int i)
{
svc = new NumberService(i);
}
public Orchestrator(NumberService providedService)
{
svc = providedService;
}
public int Get()
{
return svc.GetInt();
}
}
}
" numberService"在第二个项目中:
namespace ServiceLayer
{
public class NumberService
{
private int x;
public NumberService(int i)
{
x = i;
}
public int GetInt()
{
return x;
}
}
}
App App(在这种情况下为游戏机应用程序)又引用了演示日layer项目:
using System;
using PresentationLayer;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Orchestrator o = new Orchestrator(8);
Console.WriteLine(o.Get());
}
}
}
行Orchestrator o = new Orchestrator(8);
抛出编译器错误如下:
The type 'ServiceLayer.NumberService' is defined in an assembly that is not referenced. You must add a reference to assembly 'ServiceLayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
这似乎是因为VS无法在不知道什么是数字服务的情况下区分两个构造函数。但是,如果我更改参数的数量...
public Orchestrator(int i, bool b)
{
svc = new NumberService(i);
}
和
static void Main(string[] args)
{
Orchestrator o = new Orchestrator(8, true);
Console.WriteLine(o.Get());
}
突然很高兴编译。我觉得这两种行为之一是错误的:可以不知道给定的班级是什么,或者不是。有人对此有更好的解释或修复吗?
当您知道其使用中的使用中,您可以不理解特定的类,因为它绝对不适用于您要进行的呼叫,因为您正在指定两个参数和两个参数成员只采用一个参数。
不是可以不知道该调用是否有效,因为您不知道(例如)是否存在从int
到NumberService
的隐式转换。在这种特殊情况下,这无法更改超载分辨率(i Think ...),但在其他情况下可能会。想象一下,如果您的int
参数实际上是object
,例如...
就我个人而言,我将非常谨慎地使用某些公共API依赖于您没有参考的组件中的类型。您在黑暗中有些操作。我建议您只添加适当的参考,或使构造函数内部将其从公共API中删除。拥有公共API毫无意义,您实际上不希望其他代码能够理解。如果仅是为了单位测试,请制作构造函数internal
并使用InternalsVisibleTo
将其暴露于单元测试程序集中。
这是一个受过教育的猜测 - 我尚未检查语言规范以确认这一点 - 但我想编译器根据许多标准选择过载。如果给定方法有20个过载,则忽略与您要进行的呼叫不同的参数的过载更加有效,因为它们是显然而不是被称为。/p>
但是,一旦您缩小到具有与所传递相同的参数数量的过载列表,它将更加复杂:从传递给一个过载类型之一的内容中可能存在隐式转换,例如这使得分辨率不清楚。如果没有编译器知道所有可用参数的类型,就无法可靠地做出决定,因此失败了。
添加额外的参数意味着它不需要使用NumberService
查看过载,因此编译器不需要汇编引用来解决过载。
您可以通过启用依赖项的构造函数Overload internal
来消除错误,从而消除了编译器的需求,知道是否可以将int
施加到numberService