为什么我被迫引用未使用的构造函数中的类型?

发布于 2024-09-16 20:36:38 字数 888 浏览 5 评论 0原文

假设我有一个类 (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() {...}
}

...and < code>ClassC 甚至更简单:

public class ClassC{}

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

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

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

Let's say that I have a class (ClassA) containing one method which calls the constructor of another class, like this:

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

The class ClassB looks like this:

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

...and ClassC is even more simple:

public class ClassC{}

If I put these classes in their own assembly and compile the whole solution I don't get any errors. But if I replace the using statement with this:

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

I get a compile error asking me to add a reference to [mynamespace].ClassC in ClassA. Since I'm not calling ClassB(ClassC myC) at all this makes no sense to me - why do I have to include the types of other constructors regardless of whether I use them or not? What if ClassC was included in a licensed or hard-to-aquire assembly? Is this an example of bad design that developers should avoid or am I missing something here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

三岁铭 2024-09-23 20:36:38

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

当您调用不带参数的构造函数时,不会发生争用。只有一名候选人,因此被选中。在这种情况下,ClassA 不需要引用 ClassC

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

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

It has to do with method overload resolution when calling the ClassB constructor.

When you call the constructor with no parameters, there is no contention. There is only one candidate, so it is chosen. It is not necessary for ClassA to reference ClassC in this case.

However, when you call the constructor with one parameter, then at the outset both of the single-parameter constructors are candidates. In order to resolve this call, the compiler needs to know about ClassC. For all you know, ClassC could contain an implicit conversion operator, for example.

(Of course we know that in this particular example such an implicit conversion operator wouldn’t fire anyway because there is a perfect match that takes a string — but the method overload resolution rules are defined this way to make them very well-defined and predictable. Imagine it were designed in such a way that adding a reference could cause your code to suddenly call a different constructor overload.)

你在我安 2024-09-23 20:36:38

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

To resolve the constructor overloads, the compiler needs to know the types involved. I.e. it needs to know ClassC in order to pick the right constructor overload for ClassB.

生生漫 2024-09-23 20:36:38

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

It is because ClassC, which you have placed in a separate assembly, is part of the public interface of ClassB since it is a parameter of one of the constructors. You must reference the containing assembly of this type otherwise the compiler has no idea how to resolve the type information. In this specific case the compiler must resolve all parameter types from all constructor overloads so that it can choose the right one, but this is not a member overloading issue per se. This happens anytime the compiler must resolve type information. It can happen on return types as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文