Reputation: 6834
I have 3 level classes.
TopClass
MiddleClass
BottomClass
And MiddleClass
is derived from TopClass
and BottomClass
is derived from MiddleClass
.
I want to have a property in TopClass
which could only be accessible from TopClass
and MiddleClass
not the BottomClass
.
As I am using protected
access modifier, the protected property in TopClass
is accessible from BottomClass
.
Here are my classes to give better insight.
public class TopClass
{
private string ThisIsOnlyAccessibleForTopClass { get; set; }
protected string ThisIsOnlyAccessibleForTopClassAndMiddleClass { get; set; } // I want this to be accessible only by the MiddleClass
public string AccessibleFromEverywhere { get; set; } // this is good as it is public so accessible everywhere
public virtual void SomeWeirdFunction()
{
ThisIsOnlyAccessibleForTopClass = "I can access this here as it is grand father's private member!";
}
}
public class MiddleClass : TopClass
{
public override void SomeWeirdFunction()
{
base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "As this is a MiddleClass class, I am accessible here.. That is good!";
}
}
public class BottomClass : MiddleClass
{
public override void SomeWeirdFunction()
{
base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "I don't want this to be accessible here!";
}
}
I want ThisIsOnlyAccessibleForTopClassAndMiddleClass
to be only accessible from the MiddleClass
and TopClass
, not from BottomClass
.
How can I do that? And as I cannot do this with existing access modifiers such as protected
, public
, internal
, private
etc.. is it a sign that I am trying to break some sort of rule here?
Upvotes: 8
Views: 998
Reputation: 6610
If you have a specific MiddleClass
that should have privileged access to a member of TopClass
, you can put MiddleClass
in TopClass
as a nested type. Nested types have access to all members of their enclosing type.
public class TopClass
{
private string ThisIsOnlyAccessibleForTopClass { get; set; }
private string ThisIsOnlyAccessibleForTopClassAndMiddleClass { get; set; } // I want this to be accessible only by the MiddleClass
public string AccessibleFromEverywhere { get; set; } // this is good as it is public so accessible everywhere
public virtual void SomeWeirdFunction()
{
ThisIsOnlyAccessibleForTopClass = "I can access this here as it is grand father's private member!";
}
public class MiddleClass : TopClass
{
public override void SomeWeirdFunction()
{
base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "As this is a MiddleClass class, I am accessible here.. That is good!";
}
}
}
public class BottomClass : TopClass.MiddleClass
{
public override void SomeWeirdFunction()
{
// compilation error:
// base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "I don't want this to be accessible here!";
}
}
If you have one or more MiddleClass
classes in the same assembly as TopClass
, and all the BottomClass
classes are going to be in another assembly, you can use private protected
. It means "access to only classes that are BOTH internal
and protected
", whereas protected internal
means "access to classes that are EITHER internal
or protected
".
// in Assembly A
public class TopClass
{
private string ThisIsOnlyAccessibleForTopClass { get; set; }
private protected string ThisIsOnlyAccessibleForTopClassAndMiddleClass { get; set; } // I want this to be accessible only by the MiddleClass
public string AccessibleFromEverywhere { get; set; } // this is good as it is public so accessible everywhere
public virtual void SomeWeirdFunction()
{
ThisIsOnlyAccessibleForTopClass = "I can access this here as it is grand father's private member!";
}
}
public class MiddleClass : TopClass
{
public override void SomeWeirdFunction()
{
base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "As this is a MiddleClass class, I am accessible here.. That is good!";
}
}
// in Assembly B, which references Assembly A
public class BottomClass : MiddleClass
{
public override void SomeWeirdFunction()
{
// compile error
// base.ThisIsOnlyAccessibleForTopClassAndMiddleClass = "I don't want this to be accessible here!";
}
}
Upvotes: 8