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

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.

Related

Suppressing or avoiding Warning CA2214

I have a situation where I create an object called EntryEvent from data I receive. That data has to be parsed. The base event is supposed to kick off parsing of the data that was received through the constructor, and given to the object. The subtype knows how to pars that specific data set. Now, when compiling said code, I get the warning CA2214, that it contains a call chain to a virtual method. While it may be bad to have unforseen consequences, I do not know how to get the required behavior: Parse the received event without having to call an additional "Parse" method from the outside.
The Code in question is:
public abstract class BaseEvent
{
protected BaseEvent(object stuff)
{
this.ParseEvent();
}
protected abstract void ParseEvent();
}
public class EntryEvent : BaseEvent
{
public EntryEvent( object stuff )
: base( stuff )
{
}
protected override void ParseEvent()
{
// Parse event
}
}
According to MSDN (emphasis is mine):
When a virtual method is called, the actual type that executes the method is not selected until run time. When a constructor calls a virtual method, it is possible that the constructor for the instance that invokes the method has not executed.
So in my opinion you have these options (at least):
1) Do not disable that warning but suppress that message for your specific class(es) documenting its intended behavior (assuming you take extra care to deal with such scenario). It's not so bad if it's limited to few classes in a very controlled environment (after all...warnings are not errors and they may be ignored).
2) Remove that virtual method call from base class constructor but leave abstract method declaration there. Developers will have to implement such method and to call it in constructor they will need to mark their classes as sealed. Finally add somewhere in class/method documentation that that method must be called inside their constructor and their class must be sealed to do so.
They can forget that call but you may add (for DEBUG builds) a check when properties or methods are accessed (for example forcing, as part of class interface, to set a specific flag). If they forget to set the flag or they forget to call the method then an exception will be raised ("This object has not been built, ParseEvent() must be called in derived classes constructor.").
I don't like this method very much because it adds extra complexity but if your class hierarchy is too big (then you feel you can't use #1) or lazy initialization (described in #3) is not applicable then it may be a working solution. I'd also consider to change design to introduce a factory method that will invoke ParseEvent() for each fully constructed object.
3) Change little bit your design: defer parsing to when it's needed. For example:
public abstract class BaseEvent
{
public DateTime TimeStamp
{
get
{
if (_timestamp == null)
ParseEvent();
return _timestamp.Value;
}
protected set { _timestamp = value; }
}
protected BaseEvent(object stuff)
{
}
protected abstract void ParseEvent();
private DateTime? _timestamp;
}
Last example is only for illustration purposes, you may want to use Lazy<T> to do same task in a more coincise, clear and thread-safe way. Of course in reality you'll have more fields/properties and probably parsing will provide all values in one shot (then you just need a flag, no need for Nullable/special value on each field) This is approach I'd prefer even if it's more verbose.

C# form inheritance - Function in parent form needs to call overrided function in child

Ok - I've hit a problem that I'm having a difficult time solving.
I've got two forms - one inherits from the other. We'll call them FormParent and FormChild.
MyFunction() is defined in FormParent. I don't need to override it as it will do the same basic thing for lots of different forms, but it calls DoSomethingUnique(). DoSomethingUnique is defined in the parent and overridden in the child.
My problem is that since I'm not overriding MyFunction(), when I call it from FormChild the version of DoSomethingUnique() that it calls is the function from FormParent, not FormChild.
Is there any way to avoid overriding both functions but have the version of DoSomethingUnique() that's called be the version from FormChild?
What you are wanting to do will certainly work. You just need to make sure you have the correct modifiers in place.
In FormParent..
virtual public void DoSomethingUnique()
In FormChild
override public void DoSomethingUnique()
If you don't explicitly modify the method with override then you will be calling the method in FormParent.
Obviously replace void with your return type.

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

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 !

OOD, inheritance, and Layer Supertype

I have a question concerning holding common code in a base class and having the derived class call it, even though the derived class's trigger method has been dispatched from the base. So, base->derived->base type call stack.
Is the following look OK, or does it smell? I have numbered the flow steps...
public abstract class LayerSuperType
{
public void DoSomething() // 1) Initial call from client
{
ImplementThis(); // 2) Polymorphic dispatch
}
protected abstract void ImplementThis();
protected void SomeCommonMethodToSaveOnDuplication(string key) // 4)
{
Configuration config = GetConfiguration(key);
}
}
public class DerivedOne : LayerSuperType
{
protected virtual void ImplementThis() // 2)
{
SomeCommonMethodToSaveOnDuplication("whatever"); // 3) Call method in base
}
}
public class DerivedTwo : LayerSuperType
{
protected virtual void ImplementThis() // 2)
{
SomeCommonMethodToSaveOnDuplication("something else"); // 3) Call method in base
}
}
That looks absolutely fine. Perfect example of why you'd use an abstract class over an interface. It's a bit like a strategy pattern and I have used this fairly regularly and successfully.
Make sure that what the class doing is still dealing with one 'concern' though, only doing one task. If your base class does repository access but the objects are representing documents, don't put the functionality in the base class, use a separate repository pattern/object.
Looks like a very simplified Template Method Pattern where your sub-classes do some specific kinds of things at the right points in the implementation of your algorithm, but the overall flow is directed by a method on the base class. You've also provided some services to your sub-classes in the form of base class methods; that's ok too as long as you're good as far as SOLID goes.
Why not public abstract void DoSomething() and forget about ImplementThis() altogether?
The only reason I can see to leave ImplementThis() is if you want to maintain a consistent interface with DoSomething() which later on down the road will allow the signature of ImplementThis() to change without a breaking change to callers.
I agree that you should maintain a single concern with the class's responsibility but from an overall OOP perspective this looks fine to me. I've done similar on many occasions.
It does smell a little that SomeCommonMethodToSaveOnDuplication is being called in two different ways. It seems to be doing two unrelated things. Why not have two methods?

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.

Categories