Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια

rousso's .net blog

the .net blog of Yannis Roussochatzakis
Can't change access modifiers when inheriting from Generic Types.

Well I might be silly, but I had not run-up to this one yet. Until just now:

You cannot change the accessibility level of a class member by means of hiding when inheriting from a generic type.

Consider this example. A simple console application using two classes: MyList inherits from List<int> and My2ndList inherits from MyList. Generic type List<T> has a public method named Add that is not declared as virtual.

My intention was to completely hide the base implementation of the Add method in my derived class. In other words, let's assume that I want MyList class to not expose an Add method. What one would normally do in this case, would be to hide the method by using the new modifier and changing its access modifier from public to private like I tried to do in line 32 of the code snippet that follows.

Well. Guess what. This does not work if you are inheriting from a Generic Type. Try the code bellow then try to play around with the access modifiers in lines 32 and 47. Although I would normally assume that the code bellow would not even compile, it does!

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Text;
   4:  
   5: namespace TestGenerics
   6: {
   7:     class Program
   8:     {
   9:         static void Main(string[] args)
  10:         {
  11:             MyList myList = new MyList();
  12:             myList.Add(1);
  13:             myList.Add(2);
  14:             myList.Add(3);
  15:  
  16:             myList.Print();
  17:  
  18:             Console.WriteLine("Now the 2nd List");
  19:             
  20:             My2ndList my2ndList = new My2ndList();
  21:             my2ndList.Add(1);
  22:             my2ndList.Add(2);
  23:             my2ndList.Add(3);
  24:  
  25:             my2ndList.Print();
  26:         }
  27:  
  28:     }
  29:  
  30:     public class MyList : List<int>
  31:     {
  32:         new private void Add(int item)
  33:         {
  34:             item *= 10;
  35:             base.Add(item);
  36:         }
  37:  
  38:         public void Print()
  39:         {
  40:             foreach (int item in this)
  41:                 Console.WriteLine(item.ToString());
  42:         }
  43:     }
  44:  
  45:     public class My2ndList : MyList
  46:     {
  47:         new private void Add(int item)
  48:         {
  49:             item *= 100;
  50:             base.Add(item);
  51:         }
  52:     }
  53: }

So why am I posting about this?

Well... I didn't come across any comments on the subject on the Internet for the little I looked around and I thought it was an interesting thing to talk about.

If you know of any links discussing the subject and explaining the internals of the compiler or generics implementation in C#, then by all means please do leave a comment to this post.

If you'd like to copy/paste the code above then go get it here.

Share
Posted: Πέμπτη, 21 Φεβρουαρίου 2008 5:49 μμ από το μέλος rousso

Σχόλια:

Χωρίς Σχόλια

Έχει απενεργοποιηθεί η προσθήκη σχολίων από ανώνυμα μέλη