6

假设我有一个类 ( ClassA),其中包含一个调用另一个类的构造函数的方法,如下所示:

public class ClassA
{
    public void CallClassBConstructor()
    {
        using(ClassB myB = new ClassB()) {...}
    }
}

该类ClassB如下所示:

public class ClassB : IDisposable
{
    public ClassB(){}
    public ClassB(string myString){}
    public ClassB(ClassC myC){}
    public void Dispose() {...}
}

...而且ClassC更简单:

public class ClassC{}

如果我将这些类放在它们自己的程序集中并编译整个解决方案,我不会收到任何错误。但是如果我用这个替换 using 语句:

using(ClassB myB = new ClassB("mystring")){...}

[mynamespace].ClassC我收到一个编译错误,要求我添加对in的引用ClassA。由于我根本没有调用ClassB(ClassC myC),这对我来说毫无意义 - 为什么我必须包含其他构造函数的类型,而不管我是否使用它们?如果ClassC包含在许可或难以获取的程序集中怎么办?这是开发人员应该避免的不良设计示例,还是我在这里遗漏了什么?

4

3 回答 3

9

它与调用ClassB构造函数时的方法重载决议有关。

当你调用没有参数的构造函数时,没有争用。只有一个候选人,所以它被选中了。在这种情况下没有必要ClassA参考。ClassC

但是,当您使用一个参数调用构造函数时,一开始这两个单参数构造函数都是候选者。为了解决这个调用,编译器需要知道ClassC. 如您所知,ClassC它可能包含一个隐式转换运算符,例如。

(当然我们知道,在这个特定的例子中,这样一个隐式转换运算符无论如何都不会触发,因为存在一个接受字符串的完美匹配——但是方法重载解析规则是这样定义的,以使它们非常明确和可预测. 想象一下,它的设计方式是添加引用可能会导致您的代码突然调用不同的构造函数重载。)

于 2010-09-02T11:47:12.017 回答
1

要解决构造函数重载,编译器需要知道所涉及的类型。即它需要知道ClassC才能为ClassB.

于 2010-09-02T11:45:30.817 回答
1

这是因为ClassC您已放置在单独程序集中的 是公共接口的一部分,ClassB因为它是其中一个构造函数的参数。您必须引用此类型的包含程序集,否则编译器不知道如何解析类型信息。在这种特定情况下,编译器必须从所有构造函数重载中解析所有参数类型,以便它可以选择正确的类型,但这本身不是成员重载问题。每当编译器必须解析类型信息时,就会发生这种情况。它也可能发生在返回类型上。

于 2010-09-02T11:46:53.113 回答