How do I override a virtual method without changing the behaviour? - c#

When you override a method, you shouldn't change the behaviour of the method, you just specialise it. Therefore you have to call base.MyVirtualMethod() in the overridden method and add the specialisation code.
But I'm always wondering when I have to call the base.MyVirtualMethod(). Or from another point of view, how do I write my virtual method? Should I expect the user will call it as the first or the last thing the overridden method does?
public class Parent
{
public virtual void MyMethod(){ /* Some code*/ }
}
public class Child : Parent
{
public override void MyMethod()
{
/* Does my code goes here? */
base.MyMethod();
/* Or does my code goes here? */
}
}

Therefore you have to call base.MyVirtualMethod() in the overridden
method and add the specialisation code.
That is not always true - there are cases when you don't want to do in the derived class what the superclass is doing so you don't want to call base.
If you want to extent the base behavior you place your code before or after base call, depending on the actual problem. There is no rule 'always call base before your code'.

The base call does not have to be present. You can specify in the documentation whether the base call should be before other code, after other code, both, or neither (absent), and exactly what the nature of the other code should be. This will all depend on what you are trying to accomplish.
If you find that the best place for the additional code would really be somewhere inside the base call, then that means the base method should be split into two or more methods.

The answer is, as with many questions, "It depends".
Assume that you're extending class which writes some data to a file, and the extension needs to add more data at the end of the file (SimpleDataFile.writeFile() extended by ExtendedDataFile.writeFile()): in such a scenario, you would add your code after the call to the base method.
Now, assume your extension adds a pre-processing facility, maybe adding color to the base file output (SimpleDataFile.writeFile() extended by FancyDataFile.writeFile()): in such a scenario you would realistically act before anything is sent to the file, and your code would end up before the base call.

To answer your question accurately: don't override it :) When you override it, you will change the behaviour.
Most of the times I put new code below the calling of the base method, since it does perform this base behaviour and then some more additional behaviour. However this is not set in stone, and really depends on your needs.

I generally call the base method first to assure that any required initialization has already happened and that my code actually overrides the base behavior, instead of the other way around.
Obviously this depends on the specific situation though, there may very well be occasions where you know your code needs to run first.

It depends on what you wanna do but both are OK !

Related

Safeguard code from changes made by other programmers

In C# I have a class that is using a function to do some work. The thing is: this function needs the class to a have a specific structure in order for it to return correct results (for "specific structure" you can imagine the class using a specific set of enumeratives that the function relies on as well).
My question is: what is the best way to try and safeproof my function from future changes to the structure of the using class? Or at least have it so that if another programmer changes the class' structure my function will notify him that changes to the function itself are needed in order for everything to work correctly.
I hope everything is clear.
Thanks in advance!
+1 for unit tests as #joews suggested
If you cannot / don't want to use them, a very rough way to deal with this:
In the first line of Main, call a method CheckMyClass()
void CheckMyClass()
{
#if DEBUG
bool theClassIsOK = ...//check your class is still how it should be.
if (! theClassIsOK)
throw new ApplicationException ("something changed TheClass in a wrong way, DiG knows what's wrong with this");
#endif
}
Not elegant at all, I know.
Replace "DiG knows" with something more useful for your collegues (or ex collegues, since they will modify the class the day after you found a new job...)
The best way to make sure your function gets the dependencies it needs is to pass them in explicitly as arguments. So don't require an instance of the class as an argument, but rather each of the enumerations or other class members.
You could also consider making the class implement an interface with all the required attributes. If you distribute the interface along with your function in an assembly, people won't be able to change it.
Finally, you could put assertions into your function and return exceptions if the assertions aren't true.

C# Overriding method and returning different objects

I have a virtual method on a base class. Each time I override it, I want to return different object types. I know this is not possible, but what would be the best way to handle this situation?
Example of base method:
public virtual void clickContinue()
{
//click the continue button
}
And the method that overrides it:
public override myObject clickContinue()
{
//click then continue button
//return myObject
}
I need to do several similar overrides, all returning different objects. Again, I know this can't be done the way it's done above - I trying to figure out the best way to handle this situation.
I know this is not possible, but what would be the best way to handle this situation?
If you don't need a default implementation, you can potentially make the class generic, and return the generic type:
abstract class YourBase<T>
{
abstract T ClickContinue();
}
class YourOverride : YourBase<MyObject>
{
override MyObject ClickContinue()
{
//...
I sense an abuse of the override mechanic. The idea behind it is that you do the same thing but with different parameters. The name of the method actually should tell you what it does. So how is it possible the the very same procedure returns void (doesn't return anything) and on occasion returns something (non-void)?
Are you sure you should not have two completely different methods? This would probably make the API clearer, too.
Otherwise, consider returning always object, which happens to always be null in case (instead) of the void override.
Obviously, the generic way is better for type-safety. Returning object means you abandon typing and take over casting manually.

Purpose of "base.OnNavigatedTo(e)" inside of the OnNavigatedTo override method?

When overriding the OnNavigatedTo method in a page they place this line of code inside:
base.OnNavigatedTo(e);
I've been removing it and have not noticed any odd behavior. What is this line of code for? Are we supposed to leave it? Or is this like a place holder?
I'm pretty sure this isn't specific to the method itself, as I have seen this in different places. My guess is that this calls the default OnNavigatedTo method from the from the class that we are inheriting from (in this case Page). Its existence doesn't really make sense though, because if we wanted that why override it in the first place? Can someone explain how this works?
It isn't as picky as Android is (which crashes with SuperNotCalledException). But here's a use case for leaving it:
public class BasePage : PhoneApplicationPage
{
protected override OnNavigatedTo(....)
{
//some logic that should happen on all your pages (logging to console, etc.)
}
}
public class DetailsPage : BasePage
{
protected override OnNavigatedTo(....)
{
base.OnNavigatedTo(); //the basepage logging, etc.
//custom page logic (setup VM, querystring parameters, etc.)
}
}
In general, i'd call it. If the implementation of PhoneApplicationPage changes, and that Virtual function has more in it, you don't want to miss out ;)
(Not specific to OnNavigatedTo): This is limitation of virtual OnXXX methods (or any virtual method) - derived class formally doesn't know if base class have any non-trivial functionality. As result you have to dig into documentation (if one exists) or rely on testing to know if you should call base class or not. If you need to use someones library - calling base method is safer default.
There are different approaches to solve "do I need to call base implementation of virtual method" depending on context when you designing your own library.
You can check these things in reflector. The framework does it's job in the InternalOnNavigatedTo method, which calls the empty OnNavigatedTo virtual method:
protected virtual void OnNavigatedTo(NavigationEventArgs e)
{
}
You can delete that line, it has no function, but this is not a general rule. If you don't know what are the base functions do, leave the calls there.

C# .net - override existing built-in function + get underlying method code

Apologies if these are extremely basic questions, but let's say I'm using the void Add(T item) function of BlockingCollection:
1) How would I override the Add function, i.e. if I want to add a check at the beginning and then call the base function, is this possible to do, and if so, would the code look something like this?
protected sealed class BlockingCollection<T> : IEnumerable<T>
{
protected override void Add(T item)
{
// do something here
// call base blockingcollection add function, something like return base.Add(item)??
}
}
2) If instead of calling the base function, I wanted to actually modify the Add code, is there a way to get the underlying code for the Add function? Would I use something such as Reflection? If so, is there any way to get the underlying code without writing my own program and using reflection to get the method code (i.e. can I get the underlying method code within the Visual Studio IDE itself without having to write / compile / run code every time I want to get the underlying code of a method?)?
IEnumerable doesn't have an "Add" method; you'd have to implement your own. ICollection does, however!
Also, because IEnumerable/ICollection are interfaces, not classes, there's no existing implmementation for you to override. You have to do that part yourself.
Edit for possible additional extra super duper correctness:
If you're trying to subclass BlockingCollection and you want to do some additional "stuff" before T is added via "Add", you could do it like this:
public class Foo<T> : BlockingCollection<T>
{
public new void Add(T item)
{
base.Add(item);
base.Add(item);
}
}
So, this extremely simple implementation will add anything you put into your Foo via "Add" twice.
I hope you are aware that you are creating a brand new BlockingCollection class, you aren't modifying the System.Collections.Concurrent.BlockingCollection<T> class that's part of the BCL.
Actually modifying the library version of BlockingCollection<T>.Add would be quite difficult to say the least. It's distributed as a signed binary, and .NET doesn't provide a detours-style mechanism. Although DynamicMethod allows you to add new methods to existing classes, I don't think you can use it to replace existing methods.
1) Yes, that is the correct way to do what you are asking.
2) You use a decompiler to view source code for a library API you are choosing to override. This is done by you, the human, and not as part of program execution.
Reflection is a bit different. It allows your code to access an API at run time, but does not access nor expose the API's source code. There are a lot of resources out there, but you could start on MSDN.
Update:
Since the method you are overriding is void, you may not change the implementation by returning something. Try this:
protected override void Add(T item)
{
// do something here
// call base blockingcollection add function
base.Add(item);
// this is unnecessary, but you could do it for giggles
return;
}
If the original library has allowed you to override Add then the pseudo-code you show is along the right track. You do need a bit of modification though if I understand your question properly.
First, you would create your own class, inheriting the old class and if not already done by the old class implementing the IEnumerable interface. Of course if the old class is "sealed" you will not be able to do this.
protected sealed class MyBlockingCollection<T> : BlockingCollection<T>, IEnumerable<T>
{
protected override void Add<T>(T item)
{
}
}
now marking your class as sealed will prevent anyone from further overriding methods exposed. If the old class is marked sealed, you will not be able to do this.
To see the code, you will need to decompile the library, using a tool which could be easy or difficult depending on the level of obfuscation that may or may not be employed to keep you from doing just that.
Edit: just winging the code, you should check a reference to ensure you have the appropriate syntax for what you are trying to do.

Why is overriding static method alowed in C#

protected static new void WhyIsThisValidCode()
{
}
Why are you allowed to override static methods?
Nothing but bugs can come from it, it doensn't work as you would think.
Take the following classes.
class BaseLogger
{
protected static string LogName { get { return null; } }
public static void Log(string message) { Logger.Log(message, LogName); }
}
class SpecificLogger : BaseLogger
{
protected static string LogName { get { return "Specific"; } }
}
this is alowed, and the code
SpecificLogger.Log("test");
is altso alowed, but it doesn't do what you would think by looking at the code.
it calls Logger.Log with LogName = null.
So why is this allowed?
The new keyword does not override a method. It instead creates a new method of the same name which is independent of the original. It is not possible to override a static method because they are not virtual
You're not overriding it, you're hiding it. A normal method would exhibit exactly the same behavior so there is nothing specific to static methods here.
Hiding is only useful in a few cases. The one where I came across most often is making the return type more specific in a derived class. But I never had that occur with static methods.
One area where static functions with a certain name might be useful is if you use reflection and want to get information on each class by returning it from a method. But of course in most cases an attribute fits better.
And it's not likely to create bugs since your code produces a compiler-warning:
Warning 'StaticHiding.SpecificLogger.LogName' hides inherited member 'StaticHiding.BaseLogger.LogName'. Use the new keyword if hiding was intended.
And if you use new you should know what you're doing.
Others have pointed out that this isn't overriding, but that still leaves your original question: why are you able to do it? (But the question is really "why can you hide static methods".)
It's an inevitable feature of supporting the independent versioning of component that contain base classes and components that use those base classes.
For example, imagine that component CompB contains the base class, and some other component CompD contains a derived class. In version 1 of CompB, there might not have been any property called LogName. The author of CompD decides to add a static property called LogName.
The critical thing to understand at this point is that the author of v1 of CompD was not intending to replace or hide any feature of the base class - there was no member called LogName in the base class when they wrote that code.
Now imagine that a new version of the CompB library is released. In this new version, the author added a LogName property. What's supposed to happen in CompD? The options appear to be:
CompD no longer works because the LogName it introduces clashes with the LogName added to CompB
Somehow make the CompD's LogName replace the base CompB LogName. (It's not actually remotely clear how this could work with statics. You could envisage this with non-statics though.)
Treat the two LogName members as being completely different members that happen to have the same name. (In reality, they don't - they're called BaseLogger.LogName and SpecificLogger.LogName. But since in C# we don't always need to qualify the member name with the class, it looks like they're the same name.)
.NET chooses to do 3. (And it does that with both statics and non-statics. If you want behaviour 2 - replacement - with non-statics, then the base has to be virtual and the derived class has to mark the method as override to make it clear that they were deliberately overriding a method in the base class. C# will never make a derived class's method replace a base class's method unless the derived class explicitly stated that this is what they wanted.) This is likely to be safe because the two members are unrelated - the base LogName didn't even exist at the point where the derived one was introduced. And this is preferable to simply breaking because the latest version of the base class introduced a new member.
Without this feature, it would be impossible for new versions of the .NET Framework to add new members to existing base classes without that being a breaking change.
You say that the behaviour isn't what you expect. Actually it's exactly what I'd expect, and what you'd probably want in practice. The BaseLogger has no idea that the SpecificLogger has introduced its own LogName property. (There's no mechanism by which it could because you cannot override static methods.) And when the author of SpecificLogger wrote that LogName property, remember that they were writing against v1 of BaseLogger which didn't have a LogName, so they weren't intending that it should replace the base method either. Since neither class wants replacement, clearly replacement would be the wrong thing.
The only scenario in which you should ever end up in this situation is because the two classes are in different components. (Obviously you can contrive a scenario when they're in the same component, but why would you ever do that? If you own both pieces of code and release them in a single component, it'd be mad ever to do this.) And so BaseLogger should get its own LogName property, which is exactly what happens. You may have written:
SpecificLogger.Log("test");
but the C# compiler sees that SpecificLogger doesn't provide a Log method, so it turns this into:
BaseLogger.Log("test");
because that's where the Log method is defined.
So whenever you define a method in a derived class that isn't attempting to override an existing method, the C# compiler indicates this in the metadata. (There's a "newslot" setting in the method metadata that says, this method is meant to be brand new, unrelated to anything in the base class.)
But this gives you a problem if you want to recompile CompD. Let's say you've got a bug report due to some entirely unrelated bit of code and you need to release a new version of CompD. You compile it against the new verison of CompB. If the code you've written wasn't allowed, you wouldn't actually be able to - old code that's already compiled would work, but you wouldn't be able to compile new versions of that code, which would be a bit mad.
And so, to support this (frankly somewhat obscure) scenario, they allow you to do this. They generate a warning to let you know that you've got a naming clash here. You need to supply the new keyword to get rid of it.
This is an obscure scenario, but if you want to support inheritance across component boundaries, you need this, otherwise the addition of new public or protected members on a base class would invariably be a breaking change. That's why this is here. But it's bad practice ever to rely on it, hence the fact that you get a compiler warning. The use of the new keyword to get rid of the warning should only ever be a stopgap.
The bottom line is this: this feature exists for one reason only, and that's to get you out of a hole in situations where a new version of some base class has added a member that didn't previously exist, and which clashes with a member that's already on your derived class. If that's not the situation you're in, don't use this feature.
(I think they should actually issue an error rather than a warning when you leave out new, to make this more clear.)
Static methods and fields do not belong to class instances but to class definitions. Static methods do not play part in the virtual dispatching mechanism and are not part of the virtual method table.
They are just methods and fields on that specific class.
It may look like the methods and fields are "inherited" because you can do SpecificLogger.Log(), but that is just something to keep you from having to refer to the base class all the time.
Static methods and fields really are just global methods and fields, just the OO kind.
for my surprise following code is allowed and compiles without any error on .net Framework 4.5.1, VS 2013.
class A
{
public static void Foo()
{
}
}
class B : A
{
}
class Program
{
static void main(string[] args)
{
B.Foo();
}
}
You aren't overriding the property in the base class, but instead hiding it. The actual property used at runtime depends on what interface you're working against. The following example illustrates:
SpecificLogger a = new SpecificLogger();
BaseLogger b = new SpecificLogger();
Console.Write(a.Log); // Specific
Console.Write(b.Log); // null
In your code the Log method is actually working against the BaseLogger interface - because the Log method is part of the BaseLogger class.
Static methods and properties can not be overridden, and when you want to hide a property you should use the new keyword to denote that you're hiding something.

Categories