4

Say I have these files:

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
}

The two files are part of the same assembly. Is there any way I can make Foo accessible to MyCode.cs but not to OtherCode.cs? My question is similar to this question: C# Extension Methods only visible and accessible within one class ("private") But its accepted answer isn't really what I'm looking for. I want to make an extension method that's only visible to the code I'm working on, and according to the answer to the above question, someone could still access it by adding a "using" statement. Is there a way I can create an extension method that is only visible to my code, and nowhere else, not even by another class in the same assembly?

I ask because the syntax for calling an extension method is handy and would be useful for what I'm working on (otherwise I'd just create a private method instead), but I don't want others to see it and use it from their code in case it doesn't do what they assume it does. And thanks to Visual Studio's intellisense, my extension methods are currently showing up in the list of available methods (along with the option to add the namespace they're in).

Community
  • 1
  • 1
inejwstine
  • 678
  • 1
  • 10
  • 30
  • 2
    "but I don't want others to see it and use it from their code in case it doesn't do what they assume it does" -- then make it clear what it does? You creating yourself a lot of work to prevent someone else from making a mistake – hometoast Jan 23 '15 at 19:58
  • Can you make OtherCodeNameSpace the parent namespace? – MikeG Jan 23 '15 at 19:58
  • 1
    Name spaces in C# are organizational, they play no part in controlling accessibility. – Preston Guillot Jan 23 '15 at 20:06
  • @hometoast Essentially I want it to be like a private method, but would like to use the extension method syntax. Is that possible? – inejwstine Jan 23 '15 at 20:45
  • 1
    Also, why the downvote? I searched for an answer before asking and didn't find what I was looking for. Is my question unclear? Please let me know so I can ask better questions in the future. – inejwstine Jan 23 '15 at 20:47
  • If you can put both namespaces in the same assembly, then you can mark it as internal, then it can't be used (at least not easily) by other code that is not in the assembly. – Erik Funkenbusch Jan 23 '15 at 22:22
  • Please don't confuse type, the namespace of the type and the assembly that contains the type. Types with the same namespace can be contained in different assemblies. – Tom Blodget Jan 23 '15 at 23:49
  • You're right, namespace was a bad example. The point is I want to restrict access to my extension methods so that classes in the same assembly can't access them, not even with a using statement. I'll update my question. – inejwstine Jan 24 '15 at 14:08

4 Answers4

5

There is no such thing as a namespace-limited access modifier in the .NET platform. From the docs

public : Access is not restricted.
protected : Access is limited to the containing class or types derived from the containing class.
Internal : Access is limited to the current assembly.
protected internal: Access is limited to the current assembly or types derived from the containing class.
private : Access is limited to the containing type.

That's all you have to work with. So the answer is no.

  • Emphasizing after the update to the question, no, per the C# spec, files compiled at the same time are effectively one file. (That's in the first few sections of the spec, which is very readable, by the way.) – Tom Blodget Jan 24 '15 at 16:21
  • Darn. Ah well. I guess private static methods it is then. Thanks! – inejwstine Jan 26 '15 at 18:17
2

Extension methods are just semantic sugar that compile to the same IL as calling the static helpers directly.

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

You cannot restrict it from being called, but you can remove its visibility from Intellisense.

Simply move your extension methods to a different namespace, add a using statement in your MyCode.cs and don't include that namespace in OtherCode.cs

[update]

If you really need to restrict the caller, you could try using reflection to determine and restrict, but this is a bit overkill. Best to simply use a private static helper instead of doing this.

var frame = new System.Diagnostics.StackFrame(1, false);
var method = frame.GetMethod();
var type = method.DeclaringType;
// allow|deny type
Steve
  • 1,995
  • 2
  • 16
  • 25
0

I had a similar problem. I did not want the programmer to see my inner extension methods when configuring services in ASP.NET Core.

The solution for me was to add all extension methods to namespace Microsoft.Extensions.DependencyInjection that is used in Startup.cs and the user can see those methods. (As you would always do.)

If I wanted to "hide" something I added the extension method to MyNamespace.Extensions. If the user writes the correct name the helper for add using will show up but by default it won't be listed.

I know this is not a solution but might help someone.

androbin
  • 1,622
  • 14
  • 31
0

think about similar thing;

c# assembly, friend assembly will try InternalsVisibleTo; if your classes is closed maybe will not helpfull but you can try it;

user1005462
  • 158
  • 2
  • 7