Why would you mask a base class member? - c#

I have just learned how to mask a base class member (using new) but am missing the point as to why I would want to do that. Does masking provide us with a certain level of protection as is the case in using encapsulation? Please advise.

You will very rarely use "new" to mask a base class member.
It's mainly used for the cases where the derived class had the member first, and then it was added to the base class --- the same name for a different purpose. The new is there to that you acknowledge that you know you are using it differently. When a base member is added in C++, it just silently merges the existing method into the inheritance chain. In C#, you will have to choose between new and override, to show you know what is happening.

It's not just used for masking. It actually breaks the inheritance chain, so if you call the base class method, the method in the derived class will not be called (just the one in the base class).
You're essentially creating a new method that has nothing to do with the base class method. Hence the "new" keyword.
Keeping that in mind the "new" keyword can be used if you want to define a method with the same signature as a base type method, but having a different return type.

The only valid safe examples that I've come across is being more specific with return types or providing a set accessor on a property. I'm not saying those are the only ones, but that's all I've found.
For example, suppose you have a very simple base that looks like this:
public abstract class Base
{
public string Name { get; protected set; }
public Base(string name)
{ Name = name; }
}
You could have a derived that looks more like this:
public class Derived : Base
{
public new string Name
{
get { return base.Name; }
set { base.Name = value; }
}
public Derived(string name) : base(name)
{ }
}
Assuming business rules allows this one specific Derived to have a changeable name, I believe this is acceptable. The problem with new is that it changes behavior depending on what type the instance is viewed as. For example, if I were to say:
Derived d = new Derived("Foo");
d.Name = "Bar";
Base b = d;
b.Name = "Baz"; // <-- No set available.
In this trivial example, we're fine. We are overriding the behavior with new, but not in a breaking way. Changing return types requires a bit more finesse. Namely, if you use new to change a return type on a derived type, you shouldn't allow that type to be set by the base. Check out this example:
public class Base
{
public Base(Base child)
{ Child = child; }
public Base Child { get; private set; }
}
public class Derived
{
public Derived(Derived child) : base(child)
{ }
public new Derived Child
{ get { return (Derived)base.Child; } }
}
If I could set Child on the Base class, I could have a casting problem in the Derived class. Another example:
Derived d = new Derived(someDerivedInstance);
Base b = d;
var c = b.Child; // c is of type Base
var e = d.Child; // e is of type Derived
I can't break any business rules by treating all of my Derived classes as Bases, it's just convenient to not type check and cast.

I have just learned how to mask a base class member (using new)
FYI this feature is usually called "hiding" rather than "masking". I think of "masking" as clearing bits in a bit array.
am missing the point as to why I would want to do that.
Normally you don't want to. For some reasons to use and not use this feature, see my article on the subject from 2008:
http://blogs.msdn.com/b/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx
Does masking provide us with a certain level of protection as is the case in using encapsulation?
No, it does not.

What you are referring to is called Name Hiding. It is mostly a convenience feature. If you are inheriting from a class for which you do not control the source using new will let you change the behavior of a method even if it wasn't declared as virtual (or completely change the signature if it is virtual). The new keyword simply suppresses a compiler warning. You are basically informing the compiler that you are intentionally hiding the method from a parent class.
Delphi had the reintroduce keyword for the same reason.
What does this buy you other than a suppressed warning? Not a whole lot. You can't access the new method from a parent class. You can access it from an interface if your child class directly implements the interface (as apposed to inheriting it from its parent class). You can still call the parent class' member from the child. Any additional descendants of your class will inherit the new member rather than the one in the parent.

This is actually called member hiding. There are a couple of common scenarios where this can be appropriately used.
It allows you to work around versioning issues in which either the base or derived class author unwittingly creates a member name that collides with an existing identifier.
It can be used to simulate covariance on return types.
Regarding the first point...it is possible that an author of a base class could later add a member with the same name as an exisiting member in a derived class. The base class author may not have an knowledge of the derived classes and thus there is no expectation that she should avoid name collisions. C# supports the independent evolution of class hierarchies using the hiding mechanisms.
Regarding the second point...you may want a class to implement an interface that dictates a certain method signature and so you are locked into returning instances of a certain type only while at the same time you have subclassed that type and would really like for callers to see the concrete type instead. Consider this example.
public interface IFoo { }
public class ConcreteFoo { }
public abstract class Base
{
private IFoo m_Foo;
public Base(IFoo x) { m_Foo = x; }
public IFoo Foo { get { return m_Foo; } }
}
public class Derived
{
public Derived(ConcreteFoo x) : base(x) { }
public new ConcreteFoo Foo { get { return (ConcreteFoo)base.Foo; } }
}

Related

Properties in an Interface

In my interface, I have declared a property with setter and getter.
public interface ITestInterface
{
string AProperty { get; set; }
}
When I code my class which inherit that interface, why I need to define these two properties again?
public sealed class MyClass: ITestInterface
{
public string AProperty { get; set; }
}
Because you are not inheriting from an interface, you are implementing the interface. (although they both share same syntax :)
public class MyClass : IMyInterface { ... } //interface implementing
public class MyClass : MyBaseClass { ... } //inheriting from a class
Assume you are inheriting a candy box (not from your ancestors, in programming manner), it is something (not exactly) like you put the candy box in another box, now the outer box (the derived class, the inherited one) is inherited from candy box and have all the things candy box have, but if you want to implement (make) a candy box yourself you must build a box and put some candy in it. This is the way interfaces work.
Your interface definition only tells there is a property with a getter and setter, not how it is implemented. You could use auto-implemented properties, but you are not required to.
Following the interface, this would be a valid implementation:
public sealed class MyClass: ITestInterface
{
public string APROPERTY
{
get { return someField + " hello"; }
set { someOtherField = value; }
}
}
In an interface definition, string AProperty { get; set; } is the declaration of the property, while in a class, it means that the property is auto-implemented.
Short answer
Because interfaces contain no more than a definition of a class, and cannot contain the actual implementation of any member functions. It's by design.
Long answer
First you have to realize that properties are basically get and set member functions with some simplified syntax. The question here is therefore: why can't an interface definition contain an implementation of a member function?
Well, in some languages (most notably: C++) you can.
If you have an inheritance chain, that's basically solved through lookup tables. Say that you have member function 1, then in all the classes in the inheritance chain, there's a table which contains a pointer to function 1. Once you call a member function, the call basically grabs the first entry from the table belonging to the type of your object, and calls that. This thing is called a vtable (and for more details, see here).
Now, in C++, VTables are very transparent to the developer: each class basically has a vtable and there's no such thing as a real 'interface'. This also means that all classes can have implementations and members such as fields. If you have a class with only pure virtual members (e.g. functions without an implementation), you have the C++ equivalent of an 'interface'.
In software engineering, these classes were often called 'interface' classes, because they contain only a definition of what's going on, not the actual implementation. Interfaces have the nice property that they describe functionality without actually going into the details, thereby giving the possibility to put 'boundaries' in your code. There are a lot of use cases for this, including (RPC) communication, a lot of design patterns, and so on.
In C++, a class can derive from multiple classes (multiple inheritance) with and without an implementation. Also, because interfaces are in fact more like 'abstract' classes than like 'interfaces' in C#, this means you can also add functionality there. The vtable that was previously described therefore contains pointers to functions in all the base classes.
The problems with this start when you're starting to add functionality to interface classes. For starters, let's say you have something like this (I'll do this in sort-of C#):
interface A { Foo(); } // basically an interface.
interface B : A { Foo(); } // another interface
class B : A { void Foo() {...} } // implementation of Foo, inherits A
class D : B,C { } // inherits both B, C (and A via both B and C).
What we're interested in here is what happens if you call Foo in class D. For that, we have to construct a vtable for class D. Basically this vtable would look like this:
Foo() -> C::Foo()
This means that if you construct an object of D, and call Foo, you'll end up calling the implementation of Foo in type C:
var tmp = new D();
tmp.Foo(); // calls C::Foo()
It becomes more difficult when we're changing the definition of B into something like this:
class B : A { void Foo() {...} } // changed into an implementation
Again, we try to construct the vtable for class D and we end up with a problem:
Foo() -> C::Foo() or B::Foo()???
The problem we're facing here is: what implementation of Foo are we going to use when calling that member? Also, what constructor are we going to call? And what about destruction order? In C++ there are workarounds for this called virtual inheritance.
While designing .NET and the C# language, they thought about past experiences with multiple inheritance and the implications of virtual inheritance and decided that it's not only a difficult thing to implement, but also very confusing for developers at best. As you've seen, these problems don't exist when you just add interfaces.
So, that's why you cannot have a property (or a method) in your interface.
I think the problem here is, that the same syntax has two different meanings for interfaces and classes. AProperty { get; set; } is in an interface is the declaration-only, in a class it's an automatically implemented interface.
So that term is dependent on the context.
public interface ITestInterface
{
string AProperty { get; set; }
}
Declares the Property, but cannot implement it.
public sealed class MyClass: ITestInterface
{
public string AProperty { get; set; }
}
Implements the interface, where the property is automatically implemented (which only works for classes).
Interface contain property signatures not the actual definitions. You are actually requesting for any class implementing ITestInterface to implement get and set for AProperty. See this and this for more details.
As others say interface is just a container for your methods and properties signatures. It needs implementation but this implementation signature will be perfectly match with one that is used in interface. Also it guarantees that all of this members can be accessed in a class instance as they are by default public properties and without implementation program will not compile at all.
Let's say you have interface:
public interface ITestInterface
{
string AProperty { get; }
}
and class that implements it:
class MyClass : ITestInterface
{
public string AProperty { get { if (DateTime.Today.Day > 7) return "First week of month has past"; return "First week of month is on"; } }
}
It's not possible to use auto-implemented properties and not possible to add setter in this class because interface property lacks set accessor and auto-implemented properties requires that interface contains auto-implemented properties signature ({ get; set;}). So in your example interface just declares properties and that's it.
Just by knowing what interfaces class has inherited you know what members are there and if you just want to use (or allow user to use) some of this methods (not allowing to change anything though) you can always upcast your class instance to one of these interface types and pass it as a parameter.
I think the confusion here comes from the fact that auto properties (just the get and or set declarations) look the same in the interface and the implementation. The interface is merely a declaration (contract) of what a class must provide in order to be deemed an implementer of the interface. It is much clearer if you consider a method declaration in an interface vs its implementation in a class.
Interface = requirements;
Class = how those requirements are fulfilled
public interface ITestInterface
{
string GetAProperty();
}
public class MyClass : ITestInterface
{
public string GetAProperty()
{
// Do work...
return "Value";
}
}

cannot change access modifier on override [duplicate]

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???
Changing the access modifier of a method in a derived type is pointless that's why it's not allowed:
Case 1: Override with a more restrictive access
This case is obviously not allowed due to the following situation:
class Base
{
public virtual void A() {}
}
class Derived: Base
{
protected override void A()
}
Now we could say:
List<Base> list;
list.Add(new Derived());
list[0].A() //Runtime access exception
Case 2: Overriding with a less restrictive access modifier
What is the point? Hide the method and you are done.
Obviously if someone calls through the base type they will not have access to the new method defined in the derived type but that is consistent with how the author of the base type wanted things to be so you have no "right" to change that. If you want the specifics of the derived class call from the derived class, in which case the new method works perfectly fine.
EDIT: Expanding case 2
What I am trying to say in case 2, is that you already have the means to change accessibility of any method (virtual or not) if you want to change accessibility.
Consider the following code:
public class Base
{
protected virtual string WhoAmI()
{
return "Base";
}
}
public class Derived : Base
{
public new virtual string WhoAmI()
{
return "Derived";
}
}
public class AnotherDerived : Derived
{
public override string WhoAmI()
{
return "AnotherDerived";
}
}
With the new keyword you have effectively created a new virtual method for your Derived class with the same name and signature. Take note that it is ALLOWED to declare a new method virtual, so any class deriving from Derived will be allowed to override it.
What is not allowed is to have someone do the following:
Base newBaseObject = new Derived();
newBaseObject.WhoAmI() //WhoAmI is not accessible.
But this fact has nothing to do with being able to override WhoAmI() or not. Whatever the case this situation can never be because Base does not declare a public WhoAmI().
So in a theoretical C# where Derived.WhoAmI() could override Base.WhoAmI() there is no practical benefits in doing so because you will never be able to call the virtual method from the base class anyways, so the new option already meets your requirements.
I hope this makes it clearer.
OK, I found a small note from Eric Lippert in the Annotated C# reference:
An overridden virtual method is still considered to be a method of the class that introduced it. The overload resolution rules in some cases prefer members of more derived types ... overriding a method does not "move" where that method belongs in this hierarchy.
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.
If you change visibility modifiers from a more restrictive modifier to a less restrictive modifier you allow class clients access to methods designated for internal use. Essentially you've provided a means to alter class state that may not be safe.
Reducing visibility is impossible because if Base.Member was visible and Derived.Member was not visible, that would break the whole “Derived is a Base” 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 the new 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, your new 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 cast this to Base and bypass your property).
The question here is how to both override and new the same named member (identifier) in a subclass. That is apparently not possible. At the very least, I can say through experimentation that public new override string foo(){return "";} is not a syntax for that. However, you can get the same effect by using two subclasses:
using System;
class Base
{
protected virtual string foo()
{
return "Base";
}
public void ExhibitSubclassDependentBehavior()
{
Console.WriteLine("Hi, I am {0} and {1}.", GetType(), foo());
}
}
abstract class AbstractDerived : Base
{
protected virtual string AbstractFoo()
{
return base.foo();
}
protected override string foo()
{
return AbstractFoo();
}
}
class Derived : AbstractDerived
{
protected override string AbstractFoo()
{
return "Deprived";
}
public new string foo()
{
return AbstractFoo();
}
}
static class Program
{
public static void Main(string[] args)
{
var b = new Base();
var d = new Derived();
Base derivedAsBase = d;
Console.Write(nameof(b) + " -> "); b.ExhibitSubclassDependentBehavior(); // "b -> Hi, I am Base and Base."
Console.WriteLine(nameof(d) + " -> " + d.foo()); // "d -> Deprived"
Console.Write(nameof(derivedAsBase) + " -> "); derivedAsBase.ExhibitSubclassDependentBehavior(); // "derivedAsBase -> Hi, I am Derived and Deprived."
}
}
The intermediate subclass (AbstractDerived) uses override and introduces a new, differently-named member that the subclass and sub-subclasses can continue to override the base class’s member as they see fit. The sub-subclass (Derived) uses new to introduce the new API. Since you can only use new or override 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 ;-).
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.
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?
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#.

Base class object as argument for derived class

(Simplified) Scenario:
public class BaseClass
{
public int BaseClassInt {get; set;}
public BaseClass(int pBaseClassInt)
{ this.BaseClassInt = pBaseClassInt; }
}
public class DerivedClass : BaseClass
{
public int DerivedClassInt {get; set;}
public DerivedClass (int pBaseClassInt, int pDerivedClassInt) : base(pBaseClassInt)
{ this.DerivedClassInt = pDerivedClassInt; }
}
If I want to instantiate a DerivedClass-object I have to pass all arguments required to create a BaseClass-object and a DerivedClass-object. Also for every BaseClass-constructor I have to (at least should in my concrete case) provide a constructor with the same arguments in the derived class, plus arguments for the derived class properties. Then, if I change or delete a constructor in the base class I have to change or delete the corresponding contructor in the derived class(es).
I wonder if it is possible to use a constructor for the derived class which accepts a base class-object as an argument:
public DerivedClass(BaseClass pBaseClassObejct, int pDerivedClassInt)
{
// to make clear what I intend to do - looks silly of course
this = (DerivedClass)pBaseClassObject;
this.DerivedClassInt = pDerivedClassInt;
}
This could be called:
DerivedClass DerivedClassObject = new DerivedClass((new BaseClass(1),2);
If constructors in the base class would change, I wouldn´t have to mind it for the derived class. Is there any way to achieve this?
Think about this line for a moment:
this = (DerivedClass) pBaseClassObject;
Let's ignore the fact that you cant set this directly that way, and focus on the rest.
Imagine Giraffe and Elephant are both implementations of AfricanAnimal:
// By extension, ellie is also an AfricanAnimal
Elephant ellie = new Elephant();
// assume ellie is passed in as a param here (she can
// be, because she is an AfricanAnimal after all!):
public Giraffe(AfricanAnimal ellie)
{
this = (Giraffe) ellie; // Can't do this!
}
You can't (and would not want to) force ellie into being a giraffe, because a giraffe may have properties etc. that ellie lacks, and ellie may have properties that Giraffes don't have. Yet, using an AfricanAnimal as your parameter type there, would allow for just that.
Note: You could write that code and pass a Giraffe in, and all would be fine, but then again, that makes little sense; then you might as well use the Giraffe type as the parameter.
If you replace this with an instance variable, you would be able to compile with something like the following...
public Giraffe(AfricanAnimal ellie)
{
this.varOfTypeGiraffe = (Giraffe) ellie;
}
... but as soon as you run it with an Elephant as a a prameter, you will get an exception similar to:
InvalidCastException: Unable to cast object of type 'Elephant' to type 'Giraffe'.
TL;DR: This is a bad idea. Don't even try.
You cannot make a base constructor run from inside the body of any derived method (including the derived constructor). Even if you could, a base instance would not have retained any information about which constructor was used to instantiate it so there would be no way to know which base constructor should be called.
The above refers to the general case where a base constructor can potentially modify application state not directly related to the base class (e.g. by changing the value of static fields somewhere). You could use reflection to copy property values from a base instance to the derived instance being created, but this is practically unworkable because
It requires that you create a base instance in the first place -- what if the base is abstract, or if creating one has side effects?
You need a guarantee that the base constructor does not modify application state. But the aim here is to be independent of what the base constructors do, so you are back to square one.
No, that is not possible and should not be, because it doesn't make sense.
If it was possible and you deleted/changed the base class constructor, you would still need to change the code which creates the base class object that you would use as an argument to the derived class constructor.
Also, not all base classes are concrete. You would not be able to create an abstract base class, right?
This feature is not available. I think what you want is a little like this:
Suppose C# had a keyword allbaseargs and allowed code like this:
public class DerivedClass : BaseClass
{
public int DerivedClassInt { get; set; }
public DerivedClass (allbaseargs, int pDerivedClassInt)
: base(allbaseargs)
{
DerivedClassInt = pDerivedClassInt;
}
}
Then this could only work if BaseClass had only one (accessible) instance constructor.
The compiler should then examine the sole base constructor and substitute the magical word allbaseargs with the parameters of that constructor.
However, C# does not have this feature, and you would have to hand-code everything, which includes changeing all : base(...) calls of all derived classes when the constructor signature changes.
It is allowed to have the signature:
public DerivedClass(BaseClass pBaseClassObejct, int DerivedClassInt)
like you suggest, but you would not be able to chain the : base(...) easily. You would have to equip BaseClass with a construtor that took another instance in and copied all "state" (all instance properties and fields and such) from that other instance to "this". I do not recommend that solution.
This might be help!
Solution A: Create Inherit instead of base!
public static class Test
{
public static T Foo<T>(string text, int num) where T : BaseClass
{
T #base = (T)Activator.CreateInstance(typeof(T), new object[] { text, num });
//...
return #base;
}
public static void Main()
{
InheritClass inherit = Foo<InheritClass>("Hi there", 10);
}
}
Solution B: Copy base to inherit
public static class Test
{
public static TInherit As<TBase, TInherit>(this TBase #this) where TInherit : TBase
{
var type = typeof(TInherit);
var instance = Activator.CreateInstance(type);
foreach (var property in type.GetProperties())
if (property.CanWrite)
property.SetValue(instance, property.GetValue(#this, null), null);
return (TInherit)instance;
}
public static BaseClass Foo(string text, int num)
{
BaseClass #base = new BaseClass(text, num);
//...
return #base;
}
public static void Main()
{
InheritClass inherit = Foo("Hi there", 10).As<BaseClass, InheritClass>();
}
}
Notes: you can have simple 'As()' found here, but i prefer mine (where Inherit : TBase), where it's more safe and support converting base to inherit of inherit class.

How to tell if MemberInfo represents an override

Given the following code:
public class Base {
public virtual void Method() { }
}
public class Derived : Base {
public override void Method() { }
}
...
var baseMethodInfo = typeof(Base).GetMember("Method")[0];
var derivedMethodInfo = typeof(Derived).GetMember("Method")[0];
Is it possible to determine if the derivedMethodInfo represents a method declaration which overrides another in a base class?
In another question it was observed that had Method been declared abstract (and not implemented) in the base class, derivedMethodInfo.DeclaringType would have turned up as Base, which makes sense after reading #EricLippert's comments. I noticed that in the present example, since the derived class re-declares the method, that derivedMethodInfo.DeclaringType == derivedMethodInfo.ReflectedType, viz. Derived.
There doesn't seem to be any connection between baseMethodInfo and derivedMethodInfo, other than their names are the same and their respective declaring types appear in the same inheritance chain. Is there any better way to make the connection?
The reason I ask is that there appears to be no way to distinguish, through reflection, between the earlier example and the following one:
public class Base {
public virtual void Method() { }
}
public class Derived : Base {
public new void Method() { }
}
In this case as well, the Derived class both declares and reflects a member called Method.
A method shadowing a virtual method will have the VtableLayoutMask flag set in Attributes.
Note that an ordinary virtual method (with no similar name from a base type) will also have this flag set.
This flag appears to indicate that the method introduces a new entry in the VTable.
There's a more specific class MethodInfo which derives from MemberInfo. Note that not all kinds of members can be virtual (fields cannot, for example).
If you say
var derivedMethodInfo = typeof(Derived).GetMethod("Method");
then you can check if
derivedMethodInfo.GetBaseDefinition() == derivedMethodInfo
or not. See documentation for GetBaseDefinition() where they also have a code example.

Why can't we change access modifier while overriding methods in C#?

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???
Changing the access modifier of a method in a derived type is pointless that's why it's not allowed:
Case 1: Override with a more restrictive access
This case is obviously not allowed due to the following situation:
class Base
{
public virtual void A() {}
}
class Derived: Base
{
protected override void A()
}
Now we could say:
List<Base> list;
list.Add(new Derived());
list[0].A() //Runtime access exception
Case 2: Overriding with a less restrictive access modifier
What is the point? Hide the method and you are done.
Obviously if someone calls through the base type they will not have access to the new method defined in the derived type but that is consistent with how the author of the base type wanted things to be so you have no "right" to change that. If you want the specifics of the derived class call from the derived class, in which case the new method works perfectly fine.
EDIT: Expanding case 2
What I am trying to say in case 2, is that you already have the means to change accessibility of any method (virtual or not) if you want to change accessibility.
Consider the following code:
public class Base
{
protected virtual string WhoAmI()
{
return "Base";
}
}
public class Derived : Base
{
public new virtual string WhoAmI()
{
return "Derived";
}
}
public class AnotherDerived : Derived
{
public override string WhoAmI()
{
return "AnotherDerived";
}
}
With the new keyword you have effectively created a new virtual method for your Derived class with the same name and signature. Take note that it is ALLOWED to declare a new method virtual, so any class deriving from Derived will be allowed to override it.
What is not allowed is to have someone do the following:
Base newBaseObject = new Derived();
newBaseObject.WhoAmI() //WhoAmI is not accessible.
But this fact has nothing to do with being able to override WhoAmI() or not. Whatever the case this situation can never be because Base does not declare a public WhoAmI().
So in a theoretical C# where Derived.WhoAmI() could override Base.WhoAmI() there is no practical benefits in doing so because you will never be able to call the virtual method from the base class anyways, so the new option already meets your requirements.
I hope this makes it clearer.
OK, I found a small note from Eric Lippert in the Annotated C# reference:
An overridden virtual method is still considered to be a method of the class that introduced it. The overload resolution rules in some cases prefer members of more derived types ... overriding a method does not "move" where that method belongs in this hierarchy.
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.
If you change visibility modifiers from a more restrictive modifier to a less restrictive modifier you allow class clients access to methods designated for internal use. Essentially you've provided a means to alter class state that may not be safe.
Reducing visibility is impossible because if Base.Member was visible and Derived.Member was not visible, that would break the whole “Derived is a Base” 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 the new 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, your new 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 cast this to Base and bypass your property).
The question here is how to both override and new the same named member (identifier) in a subclass. That is apparently not possible. At the very least, I can say through experimentation that public new override string foo(){return "";} is not a syntax for that. However, you can get the same effect by using two subclasses:
using System;
class Base
{
protected virtual string foo()
{
return "Base";
}
public void ExhibitSubclassDependentBehavior()
{
Console.WriteLine("Hi, I am {0} and {1}.", GetType(), foo());
}
}
abstract class AbstractDerived : Base
{
protected virtual string AbstractFoo()
{
return base.foo();
}
protected override string foo()
{
return AbstractFoo();
}
}
class Derived : AbstractDerived
{
protected override string AbstractFoo()
{
return "Deprived";
}
public new string foo()
{
return AbstractFoo();
}
}
static class Program
{
public static void Main(string[] args)
{
var b = new Base();
var d = new Derived();
Base derivedAsBase = d;
Console.Write(nameof(b) + " -> "); b.ExhibitSubclassDependentBehavior(); // "b -> Hi, I am Base and Base."
Console.WriteLine(nameof(d) + " -> " + d.foo()); // "d -> Deprived"
Console.Write(nameof(derivedAsBase) + " -> "); derivedAsBase.ExhibitSubclassDependentBehavior(); // "derivedAsBase -> Hi, I am Derived and Deprived."
}
}
The intermediate subclass (AbstractDerived) uses override and introduces a new, differently-named member that the subclass and sub-subclasses can continue to override the base class’s member as they see fit. The sub-subclass (Derived) uses new to introduce the new API. Since you can only use new or override 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 ;-).
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.
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?
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#.

Categories

Resources