如何从另一个程序集中的内部接口派生

How to derive from an internal interface in another assembly

提问人:sbi 提问时间:8/27/2009 最后编辑:sbi 更新时间:8/28/2009 访问量:1021

问:

我是 C# 新手,所以请耐心等待。

好的,所以我在不同的程序集中有两个类需要相互引用:

namespace AssemblyA
{
  class A 
  {
    private B MyB { get; set; }
  }
}

namespace AssemblyB
{
  class B
  {
    private A MyA { get; set; }
  }
}

我知道不允许循环引用,所以我使用了一个接口:

namespace AssemblyA
{
  public interface IB
  {
     // whatever 'A' needs of 'B'
  }

  class A 
  {
    private IB MyB { get; set; }
  }
}

namespace AssemblyB
{
  class B : AssemblyA.IB
  {
    private A MyA { get; set; }
  }
}

这是可行的,但它的缺点是它暴露给世界其他地方。相反,我想做的是制作.但这样就不能从中推导出来。IBIBinternalB

在 C++ 中,我会交一个朋友并完成。我知道 C# 没有朋友(双关语不是故意的,而是注意到的),所以我不得不凑合着过日子。我读到有一个属性,但这将使整个程序集 A 可供整个程序集 B 访问,我不喜欢。有没有办法避免这种情况?B

c#

评论


答:

8赞 Noldorin 8/27/2009 #1

事实上,您被误导了 - C#/.NET 确实支持友元程序集。您希望将两个程序集标记为友元程序集,MSDN 将其定义如下:

可以从另一个程序集访问程序集中的内部类型或内部成员。

因此,只需将以下属性放在项目的某个代码文件中的任何位置(我会选择)。AssemblyInfo.cs

[assembly:InternalsVisibleTo("name_of_friend_assembly")]

评论

2赞 Noldorin 8/27/2009
@sbi:是的,你不可能让所有内部成员对整个其他程序集可见。然而,为什么这不适合你呢?当然,如果你想做这种事情,这些程序集可以相互信任,根据定义?
0赞 Noldorin 8/27/2009
@sbi:因为你同时编写了两个程序集? .NET 试图帮助你,但它只能做很多事情来防止开发人员的愚蠢行为。
1赞 pero 8/28/2009
在我看来,您在“更多封装”方面走得太远了。为什么不直接公开IB呢?
1赞 Noldorin 8/28/2009
@sbi:对。因此,您原始问题中的评论不仅不正确(它暗示一切都是公共/内部的,忽略了私人/受保护),而且您设法将其贴在最后的句子上,尽最大努力让人们错过它。:)即便如此,我讨论这个问题的后续评论应该已经完成了答案。不过,你的固执似乎无法解决。哦,侮辱任何试图回答你问题的人通常不是一个好策略。如果您希望此站点保持可访问性,那么举止文明可能是明智的。
1赞 Noldorin 8/28/2009
@sbi:不,我指的是你们库的消费者所说的“开发人员愚蠢”。不要因为不在“未回答”视图上而纠结。冷静下来,在这里对用户多一点尊重。
1赞 Bryan 8/27/2009 #2

可以使用 InternalsVisibleToAttribute

http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

评论

0赞 sbi 8/27/2009
<叹息> “我读过一个属性,但这会使整个程序集对整个程序集都可以访问,这是我不喜欢的。AB
0赞 sbi 8/28/2009
@Noldorin:回去读我的实际问题。然后阅读这个(和你的)答案。然后想一想。然后再次投票。
4赞 John Rudy 8/28/2009 #3

这里最大的问题是让程序集 B 看到程序集 A 的一个特定成员。

根据重申原始问题部分的评论,这否定了使用有据可查的属性的可行性。InternalsVisibleTo

或者是吗?

您是否考虑过创建一个新的程序集 C,其中标记了接口并将其自己的属性输出到 A 和 B?IBinternalInternalsVisibleTo

这至少以一种可控的方式暴露了 IB,而不会将所有 A 暴露给 B。我不是这个解决方案的忠实粉丝(我个人会按照建议继续在 A 上使用,然后记录我的其余内部结构以让其他人保持一致),但我理解你来自哪里——这至少解决了问题。InternalsVisibleTo

评论

0赞 sbi 8/28/2009
约翰,我已经考虑过了。对我来说,为了规避这个语法问题而必须添加一个程序集似乎是蹩脚的。无论如何,既然你是第一个真正阅读我的问题并提出建议的人,我就投了这个票。
0赞 John Rudy 8/28/2009
我仍然会问--谁在建造B,为什么它如此重要,如果他们能访问这一个,他们就不能访问其他的?默认情况下不会发生任何事情;有问题的开发人员需要手动调用这些成员。(换句话说,我同意其他答案,而不是我自己的答案:)!
0赞 sbi 8/28/2009
这两个组件都是内部的。但我不认为这很重要。多年来,我了解到封装是一种美德。我喜欢在编译时尽快收紧所有内容。我不认为上述设计有什么不寻常的,我很惊讶这在 C# 中不可能变得如此紧密。
1赞 John Rudy 8/28/2009
C# 旨在将程序集用作主要辅助功能分区之一。虽然 Heljsberg 和他的团队为什么会做出他们所做的所有决定确实无法回答,但我认为他们认为这种粒度级别是一个边缘情况,并认为程序集边界 - 并将这些类型的成员分解为新的程序集 - 是一个适当的响应,而不是可能增加的语言和运行时复杂性。
0赞 sbi 8/28/2009
@John:我想这是没有办法的。感谢您的解释。我将尝试围绕这个概念进行思考。