Search
Tuesday, September 02, 2014 ..:: Home ::.. Register  Login
   Calendar  
     
  
   Search  
     
  
   Blogroll  
     
  
   Disclosure  
All blog entries are the opinions of the author and do not necessarily reflect the opinions of their employer. All the code presented is for explanation and demonstration purposes only. Any damages incurred to your site and/or data are not the responsibility of the author. Every effort is taken to ensure the code properly compiles, however sometimes there are some hiccups and you might be required to do your own debugging.
     
  
   TechTidBits (Blog)  

Can you protect your classes? Do you know your scoping rules?

Nov 9

Written by:
Monday, November 09, 2009 9:02 PM  RssIcon

So!  You think you know your scoping rules for C# eh?  Check out this funky little nuance/difference between the CLR and C#!  This surprised me, and it might surprise you too!

CLR via C# by Jeffrey Richter, 2nd Edition

Have you ever created a class, decided to extend it with another one, then play with the access modifiers?  Did you end up with a big mess of compiler errors?  Why was that you might be asking yourself?  I know I was, well, until I read Jeffrey Richter's CLR via C# book.  SG recommended it to me and I'm glad he did.  Here's one little tidbit of useful information that helped me from going bald (well..........faster than normal! haha )

Wait a sec, what are those "access modifiers" you ask?  They're those public, protected, internal and private keywords you put on classes, methods, fields enums, etc.  You probably (ie HOPEFULLY LOL) know what their differences are (if not, there are hyperlinks, check'em out on MSDN).

When you tried to play with your method declarations, did you find you were getting compile errors?  Did you try having one method public in a base class, then try to hide it the inherited class?  How did that work for ya?  Did you have a protected method in the base class, only to try exposing it publically in the inherited class?  Ya, full of compile errors eh?  I think I can help explain a bit of what's going on.

The short answer is the scoping rules in C# have to be the same all the way down the object hierarchy.  If it started out as a protected property, then it has to be a protected property all the way through to the end.  If it's a public or private, then it is always a public or private!  

That's the easy and short answer.  Now for the "why?!"

If you look at the CLR, technically it lets you do exactly what you want.  Well, as long as you're opening up the access modifiers.  In other words, you can make a private method or property protected or public in the inherited class.  Ya, you might have to reread that one again to make sure you got it right (I'm doing it right now actually haha).  Yup, the idea is, TECHNICALLY the CLR will let you open up your methods, make them more open, to widen the access scoping rules.  The kicker here is C# doesn't let you do it (read above).

hhhmmm "whatcha talk'n'bout Willis?" 

It's the CLR which lets you widen the access to entities (your property, method, enum, etc) because to do otherwise would be a security risk.  Imagine this, you have a class with a public property, say YourAddress, then you create another class which inherits from the first class but this time, you decide to make YourAddress property private.  Let's say this is a WebService maybe or part of a Business Layer or EF, what ever.  HHHMMMMMM If you were able to do this, imagine for a second, one of your jr developers (unknowingly of course) casting the inherited class to the base class, then doing a Console.WriteLine( YourAddress) to the XML output........hhhhmmmm so much for data protection there!!!!!!!!!!!!!!!   That's why you can only "widen" your scoping rules but not narrow them.

Class diagramNow, let's see this with a bit of code to help cement this concept.  On the right is a class diagram of the sample code I've created so we/you/I can play with this a bit more.  The meat of the code is below, very simplistic I know but it's only the access modifiers we're interested in.

  public class BaseClass
  {
    //private methods can't be made virtual, so that test doesn't count,
    //no sense putting those in there, can't extend'em

    internal virtual string InternalMethod()
    {
      return "(interal InternalMethod) Go Habs Go!";
    }

    protected virtual string ProtectedMethod()
    {
      return "(protected InternalMethod) Go Habs Go!";
    }

    public virtual string PublicMethod()
    {
      return "(public InternalMethod) Go Habs Go!";
    }
  }

  public class SubClass : BaseClass
  {
    internal override string InternalMethod()
    {
      return "(interal SubClass) Habs Rock!";
    }

    protected override string ProtectedMethod()
    {
      return "(protected SubClass) Habs Rock!";
    }

    public override string PublicMethod()
    {
      return "(public SubClass) Habs Rock!";
    }
  }

See how everything matches up, protected overrides protected, public......public, etc. 

Now, let's try both "narrowing" and "widening" the access modifiers, they're both compile errors, so might as well do them both at the sametime.  I made the public method protected (narrowing) and the protected method public (widening).  The latter one is technicaly allowed by the CLR but now allowed in C#.  Doesn't matter about "the technicalities" C# don't let you do that here either way.

Changing access modifier compile errors

The idea here is simple, design your classes from the ground up properly and don't rely on fancy tricks to hide/show properties with OOP/inheritence.

Now it's time to grab a coffee and get coding!

 

 

Source Code: http://www.pchenry.com:8080/svn/blog/trunk/2009/AccessModifiersTest

Tags:
Categories:
Location: Blogs Parent Separator TechTidBits

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Add Comment   Cancel 
     
  
Copyright 1999-2012 by PCHenry.com   Terms Of Use  Privacy Statement