我有两个程序集,比如 Main 和 Sub ,其中 Sub 取决于 Main 。 主要定义了一些拥有protected internal virtual
成员的类,我想在 Sub 中覆盖这些类。我将这些成员覆盖为protected override
。
主要中有一个不相关的类,称之为 Main.Shared ,我想在 Sub 中使用,但我不是&# 39;不希望任何其他组件看到它。情况如下:
//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 之后,代码拒绝编译。错误消息说我现在必须覆盖DoStuff
protected internal override
,大概是因为它现在认为 Main 和 Sub 是相同的程序集(?)
这是一个很大的问题,因为这意味着我需要手动将每个覆盖更改为受保护的内部,并且有很多覆盖。此外,我可能希望稍后删除该属性,然后我需要再次更改所有内容。
有什么方法可以避免这样做吗? (除了完全重新设计代码库...)
我也很好奇为什么会发生这种情况。这种行为只是某种盲点,还是应该像这样工作?
答案 0 :(得分:2)
好的,我想我现在明白了。虽然C#规范并未对其进行调用,但它实际上并未提及InternalsVisibleTo
。我认为理解它的方法是你不能通过覆盖它来改变成员的可接受的呼叫站点集。
对于所有其他辅助功能修饰符,这只意味着您必须坚持使用相同的修饰符 - 但protected internal
略有不同。没有InternalsVisibleTo
,可以在原始程序集内和子类中访问(受protected
的正常规则的约束,这些规则稍微难以准确地编写但是非常简洁)。当你在另一个程序集中覆盖它时,通常必须使它protected
使它仍然只能用于子类和原始程序集 - 而不是你的“新”程序集。
但现在当你将InternalsVisibleTo
带入图片时,将其protected
减少可访问性 - 因为第二个程序集中的所有代码已经有权访问该成员。因此,您需要将其保留为protected internal
以保留它。 (第二个组件不必使其内部对原始组件可见,因为原始组件无论如何都不能引用第二个组件,因为那时你有一个循环引用。)
它仍然会失败 - 因为它可能仍然增加可访问性 - 如果你有程序集A,其内部对于程序集B是可见的,而程序集B的内部对程序集C是可见的,那么{程序集A中的{1}}方法应该对程序集A和B都可见;但是当您在程序集C中覆盖它时,您只能 使它对程序集B和C可见,或者仅对子类可见。在这一点上,你真的想让它显示为“程序集A和它所信任的程序集” - 但是没有办法表达它。
有意义吗?