In C#, we can not change access modifier while overriding a method from base class. e.g.
Class Base
{
**protected** string foo()
{
return "Base";
}
}
Class Derived : Base
{
**public** override string foo()
{
return "Derived";
}
}
This is not valid in C#, It will give compile time error.
I want to know the reason, why it's not allowed. Is there any technical problem or can it lead to something which is not consistent in terms of access restriction???
OK, I found a small note from Eric Lippert in the Annotated C# reference:
So this is an intentional rule to prevent the 'brittle base class' problem and provide better versioning, ie less problems when a base class changes.
But note that it has nothing to do with security, type-safety or object-state.
Overriding is a term which enables you to change or augment the behavior of methods in a base class. Overriding gives you the control to write new logic for an existing method.
Changing the method signature of a base class is somewhat like writing a new method instead of overriding the existing one. It contradicts the purpose of overriding a method. So maybe the reason why you cannot change the access modifier while overriding methods in C#.
if it had different access modifiers you can't really consider it the same method any more. kind of suggests a problem with the design of the model.
a better question would be why would you want to change the access modifiers?
You can make derived class's access less than the base's, but not more. Otherwise it would contradict base's definition and expose its components beyond what was intended.
Reasons are obvious. Security and Integrity of the objects.
In this particular example, what if external entities start modifying the property of the object which is protected according the base-class. Things will go haywire. What about the client-code that is written against the base-class to which all/any derived class must conform to.
Reducing visibility is impossible because if
Base.Member
was visible andDerived.Member
was not visible, that would break the whole “Derived
is aBase
” concept in OOP. However, increasing visibility is disallowed maybe because the language developers think that changing the visibility would be a mistake most of the time. However, you can always use thenew
keyword to hide base class members by introducing a member with the same name but a different behavior. This new member belongs to the derived type’s interface, so of course you can still access the base type’s interface by casting to that base type. Depending on how you write your subclass, yournew
member might effectively increase the visibility of the base class’s property—but remember that the base class’s property can still be accessed directly (e.g., a subclass of your subclass could castthis
toBase
and bypass your property).The question here is how to both
override
andnew
the same named member (identifier) in a subclass. That is apparently not possible. At the very least, I can say through experimentation thatpublic new override string foo(){return "";}
is not a syntax for that. However, you can get the same effect by using two subclasses:The intermediate subclass (
AbstractDerived
) usesoverride
and introduces a new, differently-named member that the subclass and sub-subclasses can continue tooverride
the base class’s member as they see fit. The sub-subclass (Derived
) usesnew
to introduce the new API. Since you can only usenew
oroverride
with a particular identifier only once per level of subclassing, you need two levels of subclassing to effectively use both on the same identifier.So, in a way, you can change the visibility while overriding methods—it’s just a pain and there’s no syntax I know of to accomplish it with just one level of inheritance. However, you might have to use some trick like this depending on what interfaces you’re trying to implement and what your base class looks like. I.e., this may or may not be what you actually want to do. But I still wonder why C# does not just support this to begin with. IOW, this “answer” is just a re-expression of the OP’s question with a workaround ;-).