Share via


C# 2.0: Protected member access and generics

Some time back I had posted about why protected member of a base class cannot be directly called from a derived class. The same thing holds for generic classes as well. However, protected member access rule has been updated in the C#2.0 spec to accomodate for Generics.

Consider the following

 class BClass {    protected int x;}class AClass : DClass {}class DClass : BClass {    void Foo()    {        //BClass b = new BClass();        //b.x = 5;        DClass d = new DClass();        d.x = 10;         AClass a = new AClass();        a.x = 13;     }}

The above code compiles fine because a class is allowed to access protected member of its base class (not directly though) and also of any other class (AClass) that derives from it. Obviously you cannot access the protected member of any other class.

In case of generic classes the rule got slightly modified (2.0 spec Section 20.1.7) as follows

Within a generic class G, access to an inherited protected instance member M using a primary-expression of
the form E.M is permitted if the type of E is a class type constructed from G or a class type inherited from a
class type constructed from G.

What this means is that atleast for protected member access, types constructed from the same generic class are considered the same. Contrast this with the fact that if a generic class has a static member, a seperate copy (not shared) of it used for each constructed type. The following code compiles fine

 class B<T> {    protected T x;}class E<T> : D<T>{}class D<T> : B<T> {    void F()    {        D<int> di = new D<int>();        D<string> ds = new D<string>();        di.x = 123;         ds.x =   "test"  ;          E<string> e = new E<string>();        e.x =   "test2"  ;     }} D <int> d = newD<int>(); 

So in the above code even though D<string> and D<int> are different closed constructed types they can access each other protected members. Same thing holds for E<string>.