3

我有两个程序集,比如MainSub,其中Sub取决于MainMain定义了一些具有protected internal virtual成员的类,我想在Sub中覆盖它们。我将这些成员覆盖为protected override.

Main中有一个不相关的类,称为Main.Shared,我想在Sub中使用它,但我不希望任何其他程序集看到它。情况如下:

//In assembly Main:
public class Shared
{
}
public class Parent
{
    protected internal virtual void DoStuff()
    {

    }
}
//In assembly Sub:
public class Child : Parent
{
    protected override void DoStuff()
    {
        base.DoStuff();
    }
} 

所以我InternalsVisibleTo像往常一样使用该属性。但是,在我用这个属性装饰Main之后,代码拒绝编译。错误消息说我现在必须覆盖DoStuffas protected internal override,大概是因为它现在认为MainSub是同一个程序集(?)

这是一个大问题,因为这意味着我需要手动将每个覆盖更改为受保护的内部,而且其中有很多。此外,我可能想稍后删除该属性,然后我需要再次更改所有内容。

有什么办法可以避免这样做吗?(除了代码库的完全重新设计......)

我也很好奇为什么会发生这种情况。这种行为只是某种盲点,还是应该像这样工作?

4

1 回答 1

4

好吧,我想我现在明白了。虽然 C# 规范没有提到这一点,但它实际上根本没有提及InternalsVisibleTo。我认为理解它的方法是您不能通过覆盖它来更改成员的可接受的呼叫站点集。

对于所有其他可访问性修饰符,这仅意味着您必须坚持使用相同的修饰符 - 但protected internal略有不同。如果没有InternalsVisibleTo,则可以在原始程序集和子类中访问(遵守 的正常规则protected,这些规则很难准确但简洁地编写)。当您在不同的程序集中覆盖它时,您通常必须使其protected仅可用于子类和原始程序集 - 而不是您的“新”程序集。

但是现在,当您将InternalsVisibleTo图片带入图片时,它protected降低可访问性-因为第二个程序集中的所有代码都已经可以访问该成员。因此,您需要保留它protected internal以保留它。(第二个程序集的内部结构不必对原始程序集可见,因为原始程序集无论如何都不能引用第二个程序集,因为那样您就有了循环引用。)

但是它仍然会下降 - 因为这仍然可能会增加可访问性 - 如果您有组件 A 的内部对组件 B 可见,而组件 B 的内部对组件 C 可见,那么组件 A 中的protected internal方法应该对两个组件 A 可见和乙;但是当您在程序集 C 中覆盖它时,您只能使其对程序集 B 和 C 可见,或者仅对子类可见。在这一点上,你真的想让它对“程序集 A 和它信任的程序集”可见 - 但没有办法表达这一点。

有道理?

于 2013-12-02T20:29:55.323 回答