2

I need to declare a member that is both protected AND internal. However, to my complete bafflement, I just discovered the hard way that "protected internal" actually means protected OR internal. Is there any access modifier that means protected AND internal?

isekaijin
  • 19,076
  • 18
  • 85
  • 153
  • @Rowland Shaw: I cannot show it. It is proprietary code. Oh, and also, you don't want to see the huge metaprogramming mess I am making. – isekaijin Apr 08 '11 at 14:16
  • 2
    Normally `internal` alone would be sufficient, unless for whatever reason you're allowing random people to add classes to your assembly. – Powerlord Apr 08 '11 at 14:16
  • @R. Bemrose: I know, I know. But that is equivalent to **needlessly** sacrificing object-oriented consistency for component-oriented consistency. Basically, you are saying something like "Who cares about internal consistency the internal design of my assembly, if it's going to be a black box to the outside world anyway?" – isekaijin Apr 08 '11 at 14:19
  • Updated my answer below to include a workaround. – Chris Ammerman Apr 08 '11 at 14:43
  • 2
    This may unbaffle you: http://blogs.msdn.com/b/ericlippert/archive/2008/04/24/why-can-t-i-access-a-protected-member-from-a-derived-class-part-three.aspx – Eric Lippert Apr 08 '11 at 16:37
  • @Eric: I am hardly unbaffled. As some people replied to your post, `protected` and `internal` is way more useful than `protected` or `internal`, which is nice to have, but is in no way essential. I am trying really hard and I still cannot come up with a real-world scenario in which `protected` or `internal` is the right access modifier. (But, anyway, that is the way how C# is, so I will use `internal` and shut up. Not because I like it, but because there is nothing better.) – isekaijin Apr 08 '11 at 19:52

5 Answers5

6

protected AND internal is not available in C# (or any other high level .NET language afaik). Although it is supported by the CLR and can be achieved in IL.

MattDavey
  • 8,897
  • 3
  • 31
  • 54
6

Though the CLR supports it, in C# there is no way to force a member to be protected AND internal.

Both C# and VB.NET combine access modifiers using a union, rather than intersection.

There is a workaround for this if you absolutely have to have it. It's not clean, but it works. You can create a helper class with an internal property on it, and then add a protected property of that inner class type to your class. The internal property of the protected property will only be accessible on a subclass within the owning assembly.

Example follows. I've used a generic on the chance that you might want multiple protected internal properties of different types. The generic will allow you to use the one inner class regardless of the desired property type.

public class AccessHelper<T>
{
    internal T Value { get; set; }
}

public class AClass
{
    public AClass()
    {
        InternalProperty.Value = "Can't get or set this unless you're a derived class inside this assembly.";
    }

    protected AccessHelper<String> InternalProperty
    {
        get;
        set;
    }
}
Chris Ammerman
  • 14,978
  • 8
  • 41
  • 41
  • The type of the member I want to declare as protected and internal is not even accessible outside of the assembly. Thus, your workaround does not work. – isekaijin Apr 08 '11 at 14:48
  • It will work, unless there is something else going on you haven't mentioned. Seriously, try it out. If it doesn't work, let me know why. It should work. In my example, the property InternalProperty will be visible outside the assembly, but NOT the Value property of that property, because Value is internal. That's where you store the actual value you want to be protected AND internal. – Chris Ammerman Apr 08 '11 at 14:51
  • Sorry, now I get what you proposed. But it's a really ugly thing. Whoever is going to maintain my project will find me out and stab me to death. (Besides, I would need an `AccessHelper` per class that needs to fake protected internal members.) – isekaijin Apr 08 '11 at 15:04
  • @Eduardo Actually the AccessHelper being an inner class was a mistake on my part. It can be public. Only the properties' access modifiers are relevant. I've updated the code sample to reflect this. This makes things a bit cleaner. It's still not ideal, obviously. But much better than having inner classes all over. – Chris Ammerman Apr 08 '11 at 18:15
3

Citing from Equiso's link:

BTW the CLR does have the notion of ProtectedANDInternal, but C# has no syntax to specify it. If you look at the CLR’s System.Reflection.MethodAttributes enum you’ll see both FamANDAssem as well as FamORAssem (“Family” is the CLR’s term for C#’s protected and “Assem” is C#’s internal).

DaeMoohn
  • 1,087
  • 13
  • 27
1

You can't define protected AND internal members in C#, although it is supported by the CLR (MemberAttributes.FamilyAndAssembly)

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
0

How about internal class and protected member.

Lukasz Madon
  • 14,664
  • 14
  • 64
  • 108
  • You can use attribute to set Visiblity to certain .dll but I think you've chosen wrong pattern. Insted of inheritance use Composite pattern or Visitor. – Lukasz Madon Apr 08 '11 at 14:58