【问题标题】:Can I restrict the visibility of C# extension methods to classes in the same assembly?我可以将 C# 扩展方法的可见性限制在同一程序集中的类中吗?
【发布时间】:2015-03-22 22:51:08
【问题描述】:

假设我有这些文件:

MyCode.cs

namespace MyCodeNamespace
{
  public class MyClass
  {
    //OMITTED
  }

  internal static class MyExtensions
  {
    internal static void Foo(this string str)
    {
      //OMITTED
    }
  }
}

OtherCode.cs

using MyCodeNamespace;
namespace OtherCodeNamespace
{
  //OMITTED
}

这两个文件是同一个程序集的一部分。有什么方法可以让 MyCode.cs 可以访问 Foo 而 OtherCode.cs 不能访问?我的问题类似于这个问题: C# Extension Methods only visible and accessible within one class ("private") 但它接受的答案并不是我真正想要的。我想制作一个仅对我正在处理的代码可见的扩展方法,并且根据上述问题的答案,仍然可以通过添加“使用”语句来访问它。有没有一种方法可以创建一个对我的代码可见的扩展方法,而在其他任何地方都看不到,甚至对同一程序集中的另一个类也不可见?

我问是因为调用扩展方法的语法很方便,并且对我正在处理的工作很有用(否则我只会创建一个私有方法),但我不希望其他人看到它并且从他们的代码中使用它,以防它没有按照他们假设的那样做。由于 Visual Studio 的智能感知,我的扩展方法目前显示在可用方法列表中(以及添加它们所在的命名空间的选项)。

【问题讨论】:

  • “但我不希望其他人看到它并从他们的代码中使用它,以防它没有按照他们假设的那样做”——然后明确它的作用?你为自己创造了很多工作来防止别人犯错
  • 你能让OtherCodeNameSpace成为父命名空间吗?
  • C# 中的命名空间是有组织的,它们在控制可访问性方面没有任何作用。
  • @hometoast 本质上我希望它像一个私有方法,但想使用扩展方法语法。这可能吗?
  • 另外,为什么要投反对票?我在询问之前搜索了答案,但没有找到我想要的东西。我的问题不清楚吗?请让我知道,以便我以后可以提出更好的问题。

标签: c# .net extension-methods access-modifiers class-visibility


【解决方案1】:

.NET 平台中没有名称空间限制访问修饰符之类的东西。 From the docs

public:访问不受限制。
protected :访问仅限于包含类或从包含类派生的类型。
内部:访问仅限于当前程序集。
protected internal:访问仅限于当前程序集或从包含类派生的类型。
private : 访问仅限于包含类型。

这就是您必须使用的全部内容。所以答案是

【讨论】:

  • 在更新问题后强调,不,根据 C# 规范,同时编译的文件实际上是一个文件。 (顺便说一下,这是规范的前几节,非常易读。)
  • 该死。呃,好吧。我猜想是私有静态方法。谢谢!
【解决方案2】:

扩展方法只是编译成与直接调用静态助手相同的 IL 的语义糖。

MyExtensionMethods.DoSomething(myObject);
myObject.DoSomething();

你不能限制它被调用,但你可以从 Intellisense 中移除它的可见性。

只需将扩展方法移动到不同的命名空间,在 MyCode.cs 中添加 using 语句,并且不要在 OtherCode.cs 中包含该命名空间

[更新]

如果你真的需要限制调用者,你可以尝试使用反射来确定和限制,但这有点矫枉过正。最好简单地使用私有静态助手而不是这样做。

var frame = new System.Diagnostics.StackFrame(1, false);
var method = frame.GetMethod();
var type = method.DeclaringType;
// allow|deny type

【讨论】:

    【解决方案3】:

    我遇到了类似的问题。我不希望程序员在 ASP.NET Core 中配置服务时看到我的内部扩展方法。

    我的解决方案是将所有扩展方法添加到 Microsoft.Extensions.DependencyInjection 中使用的命名空间 Startup.cs 并且用户可以看到这些方法。 (就像你经常做的那样。)

    如果我想“隐藏”某些内容,我将扩展方法添加到 MyNamespace.Extensions。如果用户输入了正确的名称,add using 的帮助器将显示,但默认情况下不会列出。

    我知道这不是一个解决方案,但可能会对某人有所帮助。

    【讨论】:

      【解决方案4】:

      想想类似的事情;

      c# assembly, friend assembly 将尝试InternalsVisibleTo; 如果您的课程已关闭,可能不会有帮助,但您可以尝试一下;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-18
        • 2010-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-03
        • 1970-01-01
        相关资源
        最近更新 更多