我有两个程序集,比如Main和Sub,其中Sub依赖于Main。Main定义了几个具有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属性。但是,在我用这个属性修饰主之后,代码拒绝编译。错误消息说,我现在必须将DoStuff重写为protected internal override,大概是因为它现在认为Main和Sub是同一个程序集(?)
这是一个大问题,因为这意味着我需要手动将每个覆盖更改为受保护的内部,其中有很多。此外,我可能希望稍后删除该属性,然后需要再次更改所有内容。
有什么办法可以避免这样做吗?(除了对代码库进行彻底重新设计之外.)
我也很好奇为什么会发生这种事。这种行为只是某种盲点,还是应该这样运作呢?
发布于 2013-12-02 20:29:55
好吧,我想我现在明白了。虽然C#规范没有提到这一点,但它实际上根本没有提到InternalsVisibleTo。我认为理解它的方法是,您不能通过重写成员来更改可接受的呼叫站点集。
对于所有其他可访问性修饰符,这只是意味着您必须坚持使用同一个修饰符--但protected internal略有不同。如果没有InternalsVisibleTo,则可以在原始程序集和子类中访问它(这取决于protected的常规规则,这些规则很难准确但简洁地编写)。当您在不同的程序集中重写它时,通常必须使它成为protected,这样它仍然只对子类和原始程序集可用,而不是对“新”程序集可用。
但是现在,当您将InternalsVisibleTo带入图片中时,使其成为protected将降低可访问性--因为第二个程序集中的所有代码都已经可以访问该成员。因此,您需要将它保存为protected internal,以保存它。(第二个程序集不必在原始程序集中看到其内部,因为原始程序集无论如何都不能引用第二个程序集,因为这样您就有了一个循环引用。)
但是,如果程序集A的内部部件对程序集B可见,而程序集B的内部部件对程序集C可见,则程序集A中的protected internal方法应该对程序集A和B都可见;但是当您在程序集C中重写它时,只能使程序集B和C或仅对子类可见。此时,您确实想让它对“程序集A及其信任的程序集”可见--但是没有办法表达出来。
讲得通?
https://stackoverflow.com/questions/20305689
复制相似问题