Is there ever a situation where derived class should hide …? - c#

Perhaps a stupid question, but assuming base class A defines a virtual method V, is there ever a situation where it would make sense for a derived class C to hide A.V by declaring a new virtual method C.V with the same signature as A.V:
class Program
{
static void Main(string[] args)
{
A a = new C();
a.Print(); // prints "this is in B class"
C c = new C();
c.Print();// prints "this is in C class"
}
}
class A
{
public virtual void Print()
{
Console.WriteLine("this is in A class");
}
}
class B:A
{
public override void Print()
{
Console.WriteLine("this is in B class");
}
}
class C : B
{
public virtual void Print()
{
Console.WriteLine("this is in C class");
}
}
Thank you

Hiding inherited virtuals is not something that should be done as part of a deliberate design. Languages support virtual hiding to make object frameworks more resilient to future change.
Example: Release 1 of object framework X does not provide a Print() function. Bob decides to extend a few of the framework X objects by defining Print() functions in descendant classes of his own. Since he plans to override them in more specific classes, he also makes the Print() function virtual.
Later, Release 2 of object framework X is released. Bob decides to upgrade his current project to use Release 2 instead of Release 1. Unbeknownst to Bob, the object framework X team also decided Print() would be a useful function to have and so they added a virtual Print() in one of the base classes of the framework.
With virtual hiding, Bob's descendant classes containing Bob's Print() implementation should compile and run fine even though a different Print() now exists in the base classes - even with a different method signature. The code that knows about the base class Print() will continue to use it, and the code that knows about Bob's Print() will continue to use it. Never the two shall meet.
Without virtual hiding, Bob's code will not compile at all until he does some non-trivial surgery to his source code to eliminate the name conflict on Print(). Some would argue this is the "correct" thing to do (refuse to compile) but realistically any rev of a base library that requires revising existing working code will not go over well with customers. They will blame the framework for breaking everything and speak ill of it.
It would be reasonable for Bob to get a compiler warning about the base Print being obscured by Bob's print, but this isn't a fatal error. It's something that Bob should probably clean up (by renaming or eliminating his Print() function) as soon as possible to avoid human confusion.

I have seen it used in scenarios where you want to automatically cast a member of a base class to narrower type from a subclass.
public interface IFoo { }
public class ConcreteFoo : IFoo { }
public abstract class Bar
{
private IFoo m_Foo;
public IFoo Foo
{
get { return m_Foo; }
}
protected void SetFoo(IFoo foo)
{
m_Foo = foo;
}
}
public class ConcreteBar : Bar
{
public ConcreteA(ConcreteFoo foo)
{
SetFoo(foo);
}
public new ConcreteFoo Foo
{
get { return (ConcreteFoo)base.Foo; }
}
}
In this scenario a reference to ConcreteBar can extract a reference to ConcreteFoo without the explicit cast while at the same time the Bar and IFoo variable references are none the wiser so all of their normal polymorphism magic still applies.

Whether it makes sense all depends on the class. If the base class functionality is something that you don't want available to your class users then you should hide it so that they don't make any mistakes with it. Though this is usually when you are consuming an API that you don't have too much control over. If it is something that you are writing it's probably better to just go back and change the access for the methods.
For instance I use an API, that I don't control, that has a lot of functionality exposed and I don't want everyone using it. So in those instances I hide what I don't want people consuming.

To join the chorus, I agree it's a bad idea. Most examples I've seen are that the developer would have liked a base class method to be virtual, but unfortunately it wasnt. Then you declare it as new and hope that nobody is calling this method via a base class pointer to your object instance.
The ability to take a virtual method and redeclare it as new virtual, that's a Darwin award category.
Beside developers, new also confuses obfuscation tools. So be warned.
Nevertheless, I recently found one useful application for a new member: I used it to redeclare a readonly public property of interface type ISomthing as a property that returned the actual type ConcreteSomething. Both returned exactly the same object reference, except in the latter case the object is returned as itself rather than an interface pointer. It saved many many downcasts.

Well, first of all, if you really mean to hide, then you want the new keyword. You don't want to just put virtual in there again.
class C : B
{
public new void Print()
{
Console.WriteLine("this is in C class");
}
}
But since the method was virtual to begin with, you aren't really hiding anything. Your derived classes are expected to override the method and give it unique behavior. However, if the method wasn't made virtual, but you really need to change it, then you can use the new keyword. Note that you cannot completely hide a method by overriding it to be private. If you try, it will just call the public implementation in the base class. The best you can do is override it to throw a NotSupportedException.
And as to why you would do this: if you wrote class A yourself, I would say you have no real reason. But if you didn't, you might have a valid reason that you don't want that method called. In one project I'm working on, I have a class derived from List<>, but I don't want Add called, I require that a special method is called so that I can better control items that get added. In that case I did a new hiding and made it throw a NotSupportedException, with a message to use the other method.

Related

Why is it required to have override keyword in front of abstract methods when we implement them in a child class?

When we create a class that inherits from an abstract class and when we implement the inherited abstract class why do we have to use the override keyword?
public abstract class Person
{
public Person()
{
}
protected virtual void Greet()
{
// code
}
protected abstract void SayHello();
}
public class Employee : Person
{
protected override void SayHello() // Why is override keyword necessary here?
{
throw new NotImplementedException();
}
protected override void Greet()
{
base.Greet();
}
}
Since the method is declared abstract in its parent class it doesn't have any implementation in the parent class, so why is the keyword override necessary here?
When we create a class that inherits from an abstract class and when we implement the inherited abstract class why do we have to use the override keyword?
"Why?" questions like this can be hard to answer because they are vague. I'm going to assume that your question is "what arguments could be made during language design to argue for the position that the override keyword is required?"
Let's start by taking a step back. In some languages, say, Java, methods are virtual by default and overridden automatically. The designers of C# were aware of this and considered it to be a minor flaw in Java. C# is not "Java with the stupid parts taken out" as some have said, but the designers of C# were keen to learn from the problematic design points of C, C++ and Java, and not replicate them in C#.
The C# designers considered overriding to be a possible source of bugs; after all, it is a way to change the behaviour of existing, tested code, and that is dangerous. Overriding is not something that should be done casually or by accident; it should be designed by someone thinking hard about it. That's why methods are not virtual by default, and why you are required to say that you are overriding a method.
That's the basic reasoning. We can now go into some more advanced reasoning.
StriplingWarrior's answer gives a good first cut at making a more advanced argument. The author of the derived class may be uninformed about the base class, may be intending to make a new method, and we should not allow the user to override by mistake.
Though this point is reasonable, there are a number of counterarguments, such as:
The author of a derived class has a responsibility to know everything about the base class! They are re-using that code, and they should do the due diligence to understand that code thoroughly before re-using it.
In your particular scenario the virtual method is abstract; it would be an error to not override it, and so it is unlikely that the author would be creating an implementation by accident.
Let's then make an even more advanced argument on this point. Under what circumstances can the author of a derived class be excused for not knowing what the base class does? Well, consider this scenario:
The base class author makes an abstract base class B.
The derived class author, on a different team, makes a derived class D with method M.
The base class author realizes that teams which extend base class B will always need to supply a method M, so the base class author adds abstract method M.
When class D is recompiled, what happens?
What we want to happen is the author of D is informed that something relevant has changed. The relevant thing that has changed is that M is now a requirement and that their implementation must be overloaded. D.M might need to change its behaviour once we know that it could be called from the base class. The correct thing to do is not to silently say "oh, D.M exists and extends B.M". The correct thing for the compiler to do is fail, and say "hey, author of D, check out this assumption of yours which is no longer valid and fix your code if necessary".
In your example, suppose the override was optional on SayHello because it is overriding an abstract method. There are two possibilities: (1) the author of the code intends to override an abstract method, or (2) the overriding method is overriding by accident because someone else changed the base class, and the code is now wrong in some subtle way. We cannot tell these possibilities apart if override is optional.
But if override is required then we can tell apart three scenarios. If there is a possible mistake in the code then override is missing. If it is intentionally overriding then override is present. And if it is intentionally not overriding then new is present. C#'s design enables us to make these subtle distinctions.
Remember compiler error reporting requires reading the mind of the developer; the compiler must deduce from wrong code what correct code the author likely had in mind, and give an error that points them in the correct direction. The more clues we can make the developer leave in the code about what they were thinking, the better a job the compiler can do in reporting errors and therefore the faster you can find and fix your bugs.
But more generally, C# was designed for a world in which code changes. A great many features of C# which appear "odd" are in fact there because they inform the developer when an assumption that used to be valid has become invalid because a base class changed. This class of bugs is called "brittle base class failures", and C# has a number of interesting mitigations for this failure class.
It's to specify whether you're trying to override another method in the parent class or create a new implementation unique to this level of the class hierarchy. It's conceivable that a programmer might not be aware of the existence of a method in a parent class with exactly the same signature as the one they create in their class, which could lead to some nasty surprises.
While it's true that an abstract method must be overridden in a non-abstract child class, the crafters of C# probably felt it's still better to be explicit about what you're trying to do.
Because abstract method is a virtual method with no implementation, per C# language specification, means that abstract method is implicitly a virtual method. And override is used to extend or modify the abstract or virtual implementation, as you can see here
To rephrase it a little bit - you use virtual methods to implement some kind of late binding, whereas abstract methods force the subclasses of the type to have the method explicitly overridden. That's the point, when method is virtual, it can be overridden, when it's an abstract - it must be overriden
To add to #StriplingWarrior's answer, I think it was also done to have a syntax that is consistent with overriding a virtual method in the base class.
public abstract class MyBase
{
public virtual void MyVirtualMethod() { }
public virtual void MyOtherVirtualMethod() { }
public abstract void MyAbtractMethod();
}
public class MyDerived : MyBase
{
// When overriding a virtual method in MyBase, we use the override keyword.
public override void MyVirtualMethod() { }
// If we want to hide the virtual method in MyBase, we use the new keyword.
public new void MyOtherVirtualMethod() { }
// Because MyAbtractMethod is abstract in MyBase, we have to override it:
// we can't hide it with new.
// For consistency with overriding a virtual method, we also use the override keyword.
public override void MyAbtractMethod() { }
}
So C# could have been designed so that you did not need the override keyword for overriding abstract methods, but I think the designers decided that would be confusing as it would not be consistent with overriding a virtual method.

What is real time use virtual and new,override methods in c#..? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
If I am having base class like below:
class A
{
public virtual void print()
{
Console.WriteLine("Base class method");
Console.Read();
}
}
And derived class which inherited from base class like below:
class B : A
{
public override void print()
{
Console.WriteLine("Child Class Method");
Console.Read();
}
}
Main method to to create the objects is below:
class Method
{
static void Main(string[] args)
{
A obj=new B();
obj.Print();
}
}
The above code will invoke the child class method. But even if I created object like B obj=new B() and did 'obj.Print()', the same output would be rendered.
So what is the use creating object like A obj=new B() and calling method like above?
On the other hand, if I change derived class method as below:
public new void print()
{
Console.WriteLine("Child Class Method");
Console.Read();
}
And if do A obj=new B(), then obj.print() will invoke the base class method. The same if I do A obj=new A() and obj.print().
So what is the point of having a base class reference variable pointing to a derived reference class object and invoking the members like above? At which scenarios should this logic be used?
You have a method with this signature:
void Print(ICollection<A> objects)
{
foreach(var obj in objects)
{
obj.print();
}
}
the print will use either B implementation or A implementation (for A it could be another child C that does not new the print method)
reading: https://stackoverflow.com/a/6162547/6460438
The reason you'd do this is for polymorphism. For example, you might have a method:
void Process(A item)
{
item.print();
}
Now you can say:
B b = new b();
Process(b);
And although the method takes an A it will dispatch to the correct implementation.
The guiding principle here is that, when you're dealing with objects, you should use the broadest type that meets your needs (The least-derived type). This is sometimes expressed as "Code to an interface, not an implementation." Don't get confused by that terminology, though. Coding against a base class is also just fine, if that's the type that meets your needs.
The reason is simple: It simplifies later maintenance and refactoring, and makes the code easier to reuse elsewhere. The type of a variable makes promises about how that variable will work. It's easier to make your functions more widely applicable if you make those promises wider. When you choose a base class for your variable type, you can be more confident about changing the underlying implementation later.
In your example, if I code against A, but create an instance of B, I can be pretty confident that later, when I add a class C : A { ... } that I could use it in this function if I wanted to. If I code against B directly, that's harder to prove.
As for how those keywords relate to this:
virtual is used to mark a method as being one that a subclass can redefine (in fact, we probably expect subclasses to redefine it, at least occasionally). You use this when there's a reasonable default implementation that will work most of the time, but still want to give a subclass a way to potentially optimize the function for its own use.
abstract is used to indicate that this class expects a subclass to "fill in" some missing details. You use this when there's no way to know how to implement a method, but you know you'll need the method. abstract methods are always virtual. If a class defines any abstract methods, then the class itself must be abstract and you can't actually create an instance of it. In my own experience, I use abstract more than virtual.
override is used to indicate that this class is actually (re-)defining the behavior of the parent class.
new in this context is slightly special. Since a parent class must explicitly grant permission to its subclasses to redefine a method, we can't just override wherever we want. That's usually a good thing, but sometimes, you need to step outside the rules. (That jerk library author "forgot" to make a method virtual and we have a major optimization that we need to perform...) That's what new is for. It gives us a way around the normal inheritance rules should they get in the way. You should use this very sparingly.

C# - force overridden method to be called by parent, not by instance

I'm trying to find a proper way to restrict/force the usage of methods in order to ensure the correct internal handling.
Given the following abstract base class
public abstract class BaseClass
{
// needs to be overriden by concrete implementation
protected abstract void CreateInternal(object dataToCreate);
// only visible method
public void Create(object dataToCreate)
{
// check the data provided <-- this is important to be done each time
CheckData(dataToCreate);
// call implementation of concrete class
CreateInternal(dataToCreate);
}
private void CheckData(object dataToCheck)
{
if(dataToCheck == null) throw new Exception("Data is not valid");
}
}
and a simple implementation
public class ChildClass : BaseClass
{
protected override void CreateInternal(object dataToCreate)
{
// do create-stuff related to ChildClass
}
}
My question: Is there a way to restrict the access to CreateInternal? In ChildClass I could create a public method
public void DoStuff(object dataToDoStuff)
{
// access protected method is not forbidden
CreateInternal(dataToDoStuff);
}
This will call CreateInternal without doing the needed checks as if it would do if called via Create of the base-class.
Is there any way to force the usage of Create prior to CreateInternal? There is no need to have this at compile-time (but it would be nice), but at least at runtime.
I have something like checking who is calling in mind.
public class ChildClass : BaseClass
{
protected override void CreateInternal(object dataToCreate)
{
// if not called via base 'Create' -> throw exception
}
}
Is there some pattern I'm not aware of or is what I'm trying to achieve too weired and simply not possible?
There is no way of really enforcing this at compile or runtime. As you well say, a virtual protected method is reachable and overridable from any derived type so you'd always have to rely on the implementation of the overriden method making the necessary checks which kind of defeats the purpose.
IMHO your best bet is to enforce this through code reviews if you can control who's extending your class. If thats not the case then, seeing that your Create method is not virtual and is simply changing the state of BaseClass, why don't you call it in the constructor? Is this possible or is your example a simplified scenario and this isn't an option? Doing this would guarantee that Create is always called first.
UPDATE: Contrary to what I said before, there are "ways" you could enforce this at runtime.
Although not shown in your example, I'm guessing there will be some kind of internal state in BaseClass that any derived class must leverage via methods, properties, fields, etc. to be of any use (inheritance would be kind of pointless otherwise). You could always set a private flag createCalled in BaseClass and make all BaseClass methods, getters (yuck) and setters check the flag and bail out with an InvalidOperationException if its not set. This would esentially render useless any derived instance not correctly initialized. Ugly but doable.
Or even simpler, if you control all potential consumers of BaseClass and any derived type out there in the wild, then just make the flag public public bool Initialized { get; }and check when consuming the object and bail out if necessary.
"Weird" would not be the word of choice of mine, but still..
As far as I can see, what you are trying to achieve is to prevent the ChildClass owner, who implemented CreateInternal()'s method body, from executing those statements without invoking CheckData() first.
Even if this works, he can still copy and paste the statements into DoStuff() method body and can execute them there.
We do not force, we guide.
People will follow your guideline, and they will be happy to see that their class is working according to it.

C# prevent base class method from being hidden by new modifier in the derived class

Here's my situation. In Java I can mark a method as final in the base/super class and there is no way a derived class can mask a method of the same signature. In C# however, the new keyword allows someone inheriting my class to create a method with the same signature.
See my example below. I need to keep the orignal.MyClass public so please don't suggest that as an answer. This seems to be a lost feature moving from Java to C#:
public class orignal.MyClass{
public void MyMethod()
{
// Do something
}
}
class fake.MyClass: orignal.MyClass {
// How to prevent the following
public new void MyMethod()
{
// Do something different
}
}
EDIT: Not a duplicate.
All answers seem to suggest, it's not possible to prevent a method from being hidden/shadowed in a derived class. This became apparent while migrating some old Java code to C#. A final method in Java will not let anybody use the same method signature in any derived class. While it's great in most scenarios that C# allows a method of same signature in the derived class, it would have been great to prevent such a behavior if warranted.
// How to prevent the following
There is no way to prevent this. It's allowed by the language.
Note that, in practice, this rarely matters. If you expect your base class to be used as your class, your method will still be called. Using new only hides the method when using the DerivedClass from a a variable declared as DerivedClass.
This means that your API, if built around MyClass, will always still call MyMethod when instances are passed into your methods.
Edit in response to comments:
If you are worried about people subclassing your class in general, the only real option you do have would be to seal your class:
public sealed class MyClass
{
This will prevent people from creating a subclass entirely. If you want to allow people to derive from your class, however, there is no way to prevent them from hiding your method in their class.
You can't prevent a public method or property being masked, but why would you? It takes a deliberate action from whoever extends the base class to do this (i.e. they need to type new), so they have intended to do it, why try and stop them?
Maybe you need to switch your pattern up a bit? If the extender must use your base method then you can put something critical in it, thus forcing them to call it. Of course this is smelly if not done correctly, so if you use this approach then mark your method as virtual, then in the documentation (or method header comments) mention that the base method must be called. This way you avoid the extender having to hide/mask your method (although they still could), but they can still extend it if they want.
I'm assuming you really want to prevent someone from overriding the method - hiding a method with new cannot be prevented, but it poses no risk to the base class, so that shouldn't be an issue.
In C# methods are not overrideable by default. So you can simply prevent someone form overriding a base method by not marking it virtual or abstract. In Java methods are virtual by default, so sealing a method by using final is necessary to prevent overriding.
I think the only way is to create interface the put your method definition within it, then let the original class to implement the interface and implement the method explicitly:
interface IAnimal
{
string diary(string notes, int sleephours);
}
class Dogs:IAnimal
{
virtual public string voice()
{
string v = "Hao Hao"; return v;
}
string IAnimal.diary(string notes,int sleephours)
{
return notes + sleep.ToString() + " hours";
}
}
class Cats:Dogs
{
public override string voice()
{
string v = "Miao Miao"; return v;
}
}
You will not use diary() method via Cats instance.
For prevent of hiding base class method you can do like this:
public class Org
{
public void Do()
{
// do something
}
}
public class Fake : Org
{
public new void Do()
{
base.Do();
// do something
}
}
here the base keyword refers to Father class.
now you called method from Father class (here is Org) in child class and now this method doesnt hide anymore.

Real life usage of new keyword to hide virtual method implementation? c#

What's the real life scenario where we will use new to provide new implementation for a virtual method in the derived class? C#
I know what it means technically. what I am looking for is a real life scenario where this will be needed.
We can always achieve the same by providing the override functionality. Why would we want to incorrect method been picked when methods call is made casted to base.
No. You can't achieve the same.
// Define the base class
class Car
{
public virtual void DescribeCar()
{
System.Console.WriteLine("Four wheels and an engine.");
}
}
// Define the derived classes
class ConvertibleCar : Car
{
public new virtual void DescribeCar()
{
base.DescribeCar();
System.Console.WriteLine("A roof that opens up.");
}
}
class Minivan : Car
{
public override void DescribeCar()
{
base.DescribeCar();
System.Console.WriteLine("Carries seven people.");
}
}
Now, if you try to do this:
public static void TestCars2()
{
Car[] cars = new Car[3];
cars[0] = new Car();
cars[1] = new ConvertibleCar();
cars[2] = new Minivan();
}
The result will be:
Car object: YourApplication.Car
Four wheels and an engine.
----------
Car object: YourApplication.ConvertibleCar
Four wheels and an engine.
----------
Car object: YourApplication.Minivan
Four wheels and an engine.
Carries seven people.
----------
Override ALWAYS override while new ONLY does it when is used as its declared type (not base one).
You can see more here
No, you can't achieve the same by overriding:
Specifying a new method allows you to vary the return type
Calling the base method may not be incorrect
One example scenario:
You're using 3rd party library Foo, which contains a class FooBase
You write your own subclass of Foo, Bar
You introduce a public method in Bar called DoSomething
In the next version of Foo, the 3rd party introduces a DoSomething method in Foo which doesn't do the same as your method. This may or may not be virtual.
At this point, you want all your existing code calling Bar.DoSomething to still call Bar.DoSomething, but all the code which calls Foo.DoSomething should still call that implementation - those callers may not even know about your method, and they may be in the third party assembly.
In the long term in that situation you would probably want to rename your method if you can (depending on how much control you have over your callers) but in the short term, making your method as new achieves exactly the behaviour you want.
This sort of thing is sometimes known as the brittle base class problem. Eric Lippert has written about it reasonably extensively, including this post back in 2004.
A virtual method can be redefined. The virtual keyword designates a method that is overridden in derived classes. We can add derived types without modifying the rest of the program. The runtime type of objects thus determines behavior.

Categories

Resources