Trouble with internal classes (error CS0051: Inconsistentaccessibility)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • dylan.miller@solimarsystems.com

    Trouble with internal classes (error CS0051: Inconsistentaccessibility)

    I'm having trouble understanding the internal access modifier. There
    are many classes in my assembly that should not be accessible outside
    of the assembly. I've used the internal access modifier for these
    classes. I have public classes that use the internal classes, but I
    get a CS0051 error if I use an internal class as a parameter to a
    protected function of a public class. For example:

    internal class InternalClass
    {
    }

    public class PublicClass
    {
    protected void ProtectedFuncti on(InternalClas s internalClass)
    {
    }
    }

    When I compile the code above, I get the following error:
    error CS0051: Inconsistent accessibility: parameter type
    'InternalClass' is less accessible than method
    'PublicClass.Pr otectedFunction (InternalClass) '

    It seems like I should be able to do this, since a protected function
    is hidden from the user of a class, and it seems like "hidden" code
    should be able to use internal classes. I assume the error occurs
    because a class could be derived from PublicClass outside of the
    assembly, but I don't plan to do that. I thought the "protected
    internal" access modifier might be the solution, but it means
    protected OR internal, where what I want is protected AND internal.

    Possible solutions:
    1) Change ProtectedFuncti on() from protected to internal. This is not
    good, because then ProtectedFuncti on() becomes accessible to any code
    in the assembly. I want ProtectedFuncti on() hidden.
    2) Change InternalClass from internal to public. This is not good,
    because a domino effect will occur and I'll end up having to change
    most of my internal classes to public to avoid the CS0051 error.

    Is there a solution I'm missing, or is this just a limitation of
    internal classes?
  • Rudy Velthuis

    #2
    Re: Trouble with internal classes (error CS0051: Inconsistent accessibility)

    dylan.miller@so limarsystems.co m wrote:
    internal class InternalClass
    {
    }
    >
    public class PublicClass
    {
    protected void ProtectedFuncti on(InternalClas s internalClass)
    {
    }
    }
    >
    When I compile the code above, I get the following error:
    error CS0051: Inconsistent accessibility: parameter type
    'InternalClass' is less accessible than method
    'PublicClass.Pr otectedFunction (InternalClass) '
    Problem is that a protected member is also accessible from outside the
    assembly, by derived classes (that is exactly why there are protected
    methods: so you can call them, but ONLY in derived classes). These
    derived classes are often not in the same assembly. But as the type of
    the parameter internalClass is not visible from outside, there would be
    no way for an external class to use such a protected method.

    So the compiler rightly claims that the visibility of the internalClass
    parameter is too low to be used in a protected method.
    --
    Rudy Velthuis http://rvelthuis.de

    "Anyone who considers arithmetical methods of producing random
    digits is, of course, in a state of sin."
    -- John von Neumann (1903-1957)

    Comment

    • Jeroen Mostert

      #3
      Re: Trouble with internal classes (error CS0051: Inconsistent accessibility)

      dylan.miller@so limarsystems.co m wrote:
      I'm having trouble understanding the internal access modifier. There
      are many classes in my assembly that should not be accessible outside
      of the assembly. I've used the internal access modifier for these
      classes. I have public classes that use the internal classes, but I
      get a CS0051 error if I use an internal class as a parameter to a
      protected function of a public class. For example:
      >
      Obviously. :-)
      internal class InternalClass
      {
      }
      >
      public class PublicClass
      {
      protected void ProtectedFuncti on(InternalClas s internalClass)
      {
      }
      }
      >
      When I compile the code above, I get the following error:
      error CS0051: Inconsistent accessibility: parameter type
      'InternalClass' is less accessible than method
      'PublicClass.Pr otectedFunction (InternalClass) '
      >
      It seems like I should be able to do this, since a protected function
      is hidden from the user of a class,
      But not from clients that derive from this class. They could see
      ProtectedFuncti on() but be unable to call it because InternalClass isn't
      accessible. This situation makes no sense, so the compiler rightfully complains.
      and it seems like "hidden" code should be able to use internal classes. I
      assume the error occurs because a class could be derived from PublicClass
      outside of the assembly, but I don't plan to do that.
      It doesn't really matter what you plan on doing, but what can actually be
      done. As it stands a class external to the assembly could inherit from this
      class, creating the problem mentioned above.
      I thought the "protected internal" access modifier might be the solution,
      but it means protected OR internal, where what I want is protected AND
      internal.
      >
      C# has no support for this, and this is arguably not a bad thing, because
      that would effectively create a rather dubious discrepancy between
      inheriting from within the assembly and inheriting from without it. Such
      scenarios are typically better solved with encapsulation rather than
      inheritance.
      Possible solutions:
      1) Change ProtectedFuncti on() from protected to internal. This is not
      good, because then ProtectedFuncti on() becomes accessible to any code
      in the assembly. I want ProtectedFuncti on() hidden.
      2) Change InternalClass from internal to public. This is not good,
      because a domino effect will occur and I'll end up having to change
      most of my internal classes to public to avoid the CS0051 error.
      >
      Is there a solution I'm missing, or is this just a limitation of
      internal classes?
      Probably both. Without knowing your scenario it's hard to tell what approach
      would be best. Marking the method "internal" seems actually fairly
      uncontroversial to me -- yes, this means the method isn't hidden, but so
      what? You're relying on the kindness of close strangers to keep the use of
      internal types to a proper level anyway. The accessibility modifiers simply
      aren't flexible enough to express every reasonable scenario, but this is a
      trade-off between flexibility and ease of use.

      You're probably best off rethinking the way you've structured your classes.
      You may be able to split off the parts that need InternalClass so they won't
      need to be exposed to outside clients. Creative use of inner classes and
      encapsulation may also be of help, but this can quickly snowball into a
      design that technically does what you want in terms of visibility but is
      highly unintuitive.

      --
      J.

      Comment

      • dylan.miller@solimarsystems.com

        #4
        Re: Trouble with internal classes (error CS0051: Inconsistentacc essibility)

        I understand that, but I'm not planning on deriving classes from
        PublicClass outside of the assembly (The sealed keyword has no effect
        on the error, by the way). I was just hoping to expose a very small
        set of public classes that could be used as an API, and hide the inner
        workings of the API from the user. If I have to change many of the
        internal classes to public to avoid the CS0051 error, it's not as
        elegant, since such classes are not meant to be used outside of the
        assembly.

        I guess this is a feature of C# that I'm still wrapping my head
        around. Internal classes just don't seem as useful with this
        limitation.

        Comment

        • dylan.miller@solimarsystems.com

          #5
          Re: Trouble with internal classes (error CS0051: Inconsistentacc essibility)

          Thanks Jeroen and Rudy. I understand things much better now, and I
          guess there isn't any way around this other than restructuring the
          code. I can think of some convoluted ways to keep my minimal set of
          public classes (API) as well as keep functions protected rather than
          internal, but it's hard to justify making the code more complex when
          simply changing the access modifiers makes the problems go away, so
          I'll probably end up going with the #1 or #2 solution in my original
          post.

          Comment

          • Rudy Velthuis

            #6
            Re: Trouble with internal classes (error CS0051: Inconsistent accessibility)

            dylan.miller@so limarsystems.co m wrote:
            I understand that, but I'm not planning on deriving classes from
            PublicClass outside of the assembly (The sealed keyword has no effect
            on the error, by the way).
            Hmmm... I guess that the compiler has that as a general rule, and
            simply disregards the sealed keyword in this respect.
            --
            Rudy Velthuis http://rvelthuis.de

            "Ask her to wait a moment - I am almost done."
            -- Carl Friedrich Gauss (1777-1855), while working, when
            informed that his wife is dying

            Comment

            • Jeroen Mostert

              #7
              Re: Trouble with internal classes (error CS0051: Inconsistent accessibility)

              Rudy Velthuis wrote:
              dylan.miller@so limarsystems.co m wrote:
              >
              >I understand that, but I'm not planning on deriving classes from
              >PublicClass outside of the assembly (The sealed keyword has no effect
              >on the error, by the way).
              >
              Hmmm... I guess that the compiler has that as a general rule, and
              simply disregards the sealed keyword in this respect.
              There's not much point to declaring the class sealed anyway, because then
              there's no way of using the protected method outside the class. The compiler
              will issue a warning that says as much. You may as well declare the method
              private in that case, and then the error of course disappears.

              --
              J.

              Comment

              • =?ISO-8859-1?Q?Lasse_V=E5gs=E6ther_Karlsen?=

                #8
                Re: Trouble with internal classes (error CS0051: Inconsistentacc essibility)

                dylan.miller@so limarsystems.co m wrote:
                I understand that, but I'm not planning on deriving classes from
                PublicClass outside of the assembly (The sealed keyword has no effect
                on the error, by the way). I was just hoping to expose a very small
                set of public classes that could be used as an API, and hide the inner
                workings of the API from the user. If I have to change many of the
                internal classes to public to avoid the CS0051 error, it's not as
                elegant, since such classes are not meant to be used outside of the
                assembly.
                >
                I guess this is a feature of C# that I'm still wrapping my head
                around. Internal classes just don't seem as useful with this
                limitation.
                What about protected internal?
                If you don't intend the method to be available outside the assembly
                anyway, internal might work.

                --
                Lasse Vågsæther Karlsen
                mailto:lasse@vk arlsen.no
                Blogger ist ein Veröffentlichungs-Tool von Google, mit dem du ganz einfach deine Gedanken der Welt mitteilen kannst. Mit Blogger kannst du problemlos Texte, Fotos und Videos in deinem persönlichen Blog oder deinem Team-Blog veröffentlichen.

                PGP KeyID: 0xBCDEA2E3

                Comment

                • dylan.miller@solimarsystems.com

                  #9
                  Re: Trouble with internal classes (error CS0051: Inconsistentacc essibility)

                  What about protected internal?
                  If you don't intend the method to be available outside the assembly
                  anyway, internal might work.
                  When you mark a function protected internal, it's visible to all code
                  inside the assembly as if it were public (not good), and it's also
                  visible outside the assembly as a protected function, so I'd still get
                  the error.

                  Comment

                  • Rudy Velthuis

                    #10
                    Re: Trouble with internal classes (error CS0051: Inconsistent accessibility)

                    Jeroen Mostert wrote:
                    Rudy Velthuis wrote:
                    dylan.miller@so limarsystems.co m wrote:
                    I understand that, but I'm not planning on deriving classes from
                    PublicClass outside of the assembly (The sealed keyword has no
                    effect on the error, by the way).
                    Hmmm... I guess that the compiler has that as a general rule, and
                    simply disregards the sealed keyword in this respect.
                    >
                    There's not much point to declaring the class sealed anyway, because
                    then there's no way of using the protected method outside the class.
                    Correct. Then it can just as well be pivate.

                    --
                    Rudy Velthuis http://rvelthuis.de

                    "If you gaze long into an abyss, the abyss will gaze back into
                    you." -- Friedrich Nietzsche (1844-1900)

                    Comment

                    Working...