Delegates and inheritance in c# - c#

I have a bit of a problem with inheritance of delegates. Delegate as far as i understand is a pointer to a pair: an instance and a method, the thing is this is the method referenced in the creation of the delegate, and not affected by inheritance. So, this won't work:
public class BaseObject {
public delegate void del();
public BaseObject() {
next=Method;
}
public del next;
public void ExecuteNext() {
next();
}
public virtual void Method() {
Debug.Log("BASE");
}
}
public class InheritedObject:BaseObject {
override public void Method() {
Debug.Log("INHERITED");
}
}
...
(new InheritedObject()).ExecuteNext();
Execute runs the base Method(), I want it to run the inherited Method(). I have found some way around, but it is inefficient, distracting and very error prone, anyway here's the current working version that I'd like to get rid of:
class BaseObject {
public delegate void del();
BaseObject() {
next=DoMethod; /// using DoMethod here
}
public del next;
public void ExecuteNext() {
next();
}
public void DoMethod() { /// using DoMethod here
Method();
}
public virtual void Method() {
// do base
}
}
class InheritedObject:BaseObject {
override public void Method() {
// do inherited
}
}
...
(new InheritedObject()).Execute();
This DoMethod aproach works but has many problems,
lots of useless code
error prone when using the class - easy to mistake obj.next=DoMethod with obj.next=Method
error prone when inheriting the class - I have to remember to not to inherit the DoMethod, and lots of virtual and overrides.
Any suggestions how can I do that better? Perhaps some annotation magic that does the DoMethod by itself? I've already thought of dictionaries - they aren't good here, they add even another level of confusion (Mono, .NET 2, Unity3d framework)

You could replace next=DoMethod; with next= ()=>Method(); which is essentially the same, but doesn't require you to define an extra method on your class.

In your first example, you are assigning the result of Method(); to the delegate, so naturally that means that the Method method (ahem) will be executed at that point to assign a value. Ignoring the fact that Method is void (which won't compile).
In the second example, you are assigning a reference to the method (which doesn't have to be an instance method) to the delegate, which allows you to execute the del at a later stage.
The following works for me:
class Program
{
static void Main(string[] args)
{
var baseClass = new BaseObject();
baseClass.Execute();
var derivedClass = new DerivedObject();
derivedClass.Execute();
Console.ReadKey();
}
}
class BaseObject
{
public delegate void SomethingDelegate();
public SomethingDelegate Delegate;
public BaseObject()
{
Delegate += Something;
}
public virtual void Something()
{
Console.WriteLine("Base Class");
}
public void Execute()
{
Delegate();
}
}
class DerivedObject : BaseObject
{
public override void Something()
{
Console.WriteLine("Derived Class");
}
}
In the above example, the fact that the delegate pointer is expressed as a pointer to the Something method (of BaseObject), because the method is virtual, the call is still correctly dispatched to the overriden Something method (of DerivedObject).
Are you not seeing the same behaviour?

No, Execute will run the inherited method. After making some correction to the code I could test it:
public class BaseObject {
public delegate void del();
public BaseObject() {
next = Method;
}
public del next;
public void Execute() {
next();
}
public virtual void Method() {
Console.WriteLine("base");
}
}
public class InheritedObject : BaseObject {
override public void Method() {
Console.WriteLine("inherited");
}
}
Called:
(new InheritedObject()).Execute();
Output:
inherited

Related

Accessing a private method in a overridden public method

I am currently having some issues with accessing a private method from a overriden public method.
My situation is like this: I have a compiled .dll file which consist basically of this
public class OriginalHandler
{
public virtual void Request()
{
RedirectIfConditionIsFulfilled()
this.PeformRequest()
}
protected virtual bool PeformRequest()
{
}
private static void RedirectIfConditionIsFulfilled()
{
}
}
I need to alter the method PeformRequest(), So i make a public class, which inherit OriginalHandler and override the method as such:
public class ModifiedOriginalHandler : OriginalHandler
{
protected override bool PeformRequest()
{
}
}
To ensure that this method doesn't violate an "impact" scope, I have to ensure that it only get evaluated on certain sites,
We use this to ensure that HttpRequestProcess ONLY impact the desired site using this
namespace Sitecore.Sharedsource.Pipelines.HttpRequest
{
using System.Collections.Generic;
using Assert = Sitecore.Diagnostics.Assert;
using S = Sitecore;
public abstract class SiteSpecificHttpRequestProcessor: S.Pipelines.HttpRequest.HttpRequestProcessor
{
public abstract List<string> _sites;
public sealed override void Process(S.Pipelines.HttpRequest.HttpRequestArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (S.Context.Site == null || !this._sites.FirstOrDefault(S.Context.Site.Name))
{
return;
}
this.DoProcess(args, this._sites.FirstOrDefault(S.Context.Site.Name));
}
protected abstract void DoProcess(S.Pipelines.HttpRequest.HttpRequestArgs args, string);
}
}
So include my ModifiedOriginalHandler to include this
public class SiteSpecificModifiedOriginalHandler: SiteSpecificHttpRequestProcessor
{
Public override List<String> _sites => new[]
{
"www.only.com" , "www.boat.com"
};
public virtual HttpContext GetHttpContext()
{
return HttpContext.Current;
}
public override void DoProcess(HttpRequestArgs args, string)
{
var mediaRequest = new ModifiedOriginalHandler ();
var context = GetHttpContext();
var site = Sitecore.Context.Site;
if (site == null)
{
return;
}
if (string != null)
{
mediaRequest.Request(context);
}
else
{
OriginalHandler baseClass = mediaRequest;
baseClass.Request(context);
}
}
}
This Is where I am having a problem, I can from the SiteSpecificModifiedOriginalHandler not call the protected method PeformRequest,
but can call the public method Request which internally calls the desired function, so I make an override function,
to ensure that the original is not being called but my modified version
public class ModifiedOriginalHandler : OriginalHandler
{
protected override bool PeformRequest()
{
}
public override void Request()
{
RedirectIfConditionIsFulfilled()
this.PeformRequest()
}
}
Which is where I am having my problem, RedirectIfConditionIsFulfilled is a private method,
and I can in no way make this method call as such. I could in my overridden function remove this call, but that would
require RedirectIfConditionIsFulfilled to be removed, which would alter the original functionality, which i don't want to do.
So how do i overcome this?
How do i access a private method in a overriden public method?
If you have access to OriginalHandler implementation then make the derived class a nested one:
class A {
private void Foo() { }
protected virtual void Bar() { }
public class B: A {
protected override void Bar() {
Foo(); \\ legal } } }
If you don’t then barring reflection there is no way to access from an external type a private member of another type.
You can't access a private method from an inherited class. (But you know that.)
But your question didn't give any reason why your method shouldn't be protected, which would expose it to inherited classes.
What you're describing is exactly why protected exists.
A nested class will work, but I don't recommend it unless you want every single inherited class that needs the private method to be nested inside the base class. What if some of those inherited classes have their own private methods and even more inherited classes need to access those? You'd have to nest classes inside your nested classes.

C# delegate for function with no return value and one parameter that allows sub type classes (as parameter)

I'm looking for a delegate that encapsulates a method that return no value and take one parameter, like Action< T > does, but unfortunately that delegate does not match with method taking a child type as parameter...
That's what I'm trying to do:
public class BaseType
{
public BaseType()
{
}
}
public class ChildType : BaseType
{
public ChildType()
{
}
}
public class Test
{
public delegate void CallBackHandler(BaseType p);
public Test()
{
CallBackHandler clbk1 = callBackA;
CallBackHandler clbk2 = callBackB; //That line does not compile
//->'No overload for 'callBackB' matches delegate 'Test.CallBackHandler'
}
private void callBackA(BaseType p)
{
}
private void callBackB(ChildType p)
{
}
}
I read about covariance, contravariance, etc... I know it deals with the herited type casting but I'm a little bit confused about all of this...
Which delegate should I use to make my code work ?
This is the classic type safety problem that strong typing was created to solve.
Here's an example
abstract class Vehicle
{
public virtual void MethodSlot1_StartEngine() { }
public virtual void MethodSlot2_StopEngine() { }
}
class Car : Vehicle
{
public virtual void MethodSlot3_OpenGasTank() { }
}
class NuclearSubmarine : Vehicle
{
public virtual void MethodSlot3_FireAllNuclearMissiles() { }
}
class VehicleUser
{
public delegate void OpenGasTankMethod(Car car);
public void OpenGasTank(Vehicle vehicle, OpenGasTankMethod method)
{
//it's stopping you here from firing all nuclear weapons
//by mistaking your car's gas tank for the armageddon switch
method(vehicle);
}
}
When the compiler emits a virtual method call it just compiles an index into a lookup table. If you could pass in a NuclearSubmarine where a Car is required merely because they are both Vehicles, then you could think you are calling Car methods (like opening your gas tank) when in fact you are just making the Fallout series of games a reality.
In response to your comment, this should get you started:
class Blah
{
private List<Action<object>> _handlers = new List<Action<object>>();
public void AddListener<T>(Action<T> handler)
{
//graceful type checking code goes in here somewhere
_handlers.Add(o => handler((T) o));
}
void RaiseEvent(object eventArgs)
{
foreach (var handler in _handlers) handler(eventArgs);
}
}
You can't do this since it is not safe. If it were allowed you could do:
class OtherChild : BaseType { }
CallBackHandler clbk2 = callBackB;
clbk2(new OtherChild());
and pass an instance of OtherChild to a delegate which requires an instance of ChildType. Note that the following is safe and compiles:
public delegate void CallBackHandler(ChildType p);
CallBackHandler clbk1 = callBackA;
CallBackHandler clbk2 = callBackB;
Declare the delegate as
public delegate void CallBackHandler(ChildType p)
If the handler could accept and should act on instances of BaseType, what would happen if you passed in an instance of a new class NewChildType? Nobody knows, which is the reason why you can't here.

Same template method interface applied on base and derived class

I have a little difficulty to explain the problem clearly in words so i'll start with the code immediately:
public interface ITemplate
{
bool DoSomething(string a);
}
public class Worker
{
public void DoSomeWork(ITemplate subcontractor)
{
try {
//Do some work...
if(subcontractor.DoSomething("hello"))
{
//Do some more work
}
}
catch(InvalidOperationException) {/*...*/}
//catch(Exception2) {/*...*/}
//catch(Exception3) {/*...*/}
//catch(Exception4) {/*...*/}
}
}
public class BaseClass : ITemplate
{
public void myFunction1()
{
Worker worker = new Worker();
worker.DoSomeWork(this);
}
public bool DoSomething(string a)
{
//Some code here
return true;
}
}
public class DerivedClass : BaseClass, ITemplate
{
public void myFunction2()
{
Worker worker = new Worker();
worker.DoSomeWork(this);
}
public bool DoSomething(string a)
{
//Some other code here
return true;
}
}
With this structure, if i call myDerivedClass.myFunction1(), the worker.DoSomeWork() function will execute DerivedClass.DoSomething(), but i want BaseClass.DoSomething() to be executed in that context, how can i do ?
Maybe it is not possible to achieve what i'm trying to do in that context with the template method design pattern.
The initial problem was that i need a method to execute code, but some part of this code is code is variable according on what object called the method.
Is there another way to do that without if(typeOf(subcontractor) == ...) which is not a very good practice, i would like the variable part of the code to be stored and executed inside the caller object.
Could i pass a delegate or something in the parameter instead of sending the whole caller object ?? i'm not very used to work with delegate/etc but i think it might be helpful for my problem, am i right ?
thanks
Jonathan
That is the correct behavior and is how polymorphism works. If you have an instance of the derived class DerivedClass and you have overridden a method, say DoSomething, then all calls to the method DoSomething in the code of the base class will go through the overridden method in the derived class if dealing with an instance of the derived type.
If you wish the code in the base class to be executed, then you need to either not override the method, or call the base class method from the derived class:
public class BaseClass
{
public virtual void MyMethod()
{
// Do some stuff...
}
}
public class DerivedClass : BaseClass
{
public override void MyMethod()
{
// Do something new...
// Do the stuff in BaseClass.MyMethod()
base.MyMethod();
}
}
DerivedClass is an ITemplate since it inherits from BaseClass which is an ITemplate. You don't need DerivedClass to directly implement ITemplate.
Also, as said above, the code you posted won't compile.
public interface ITemplate
{
bool DoSomething(string a);
}
public class Worker
{
public void DoSomeWork(ITemplate subcontractor)
{
//Do some work...
if(subcontractor.DoSomething("hello"))
{
//Do some more work
}
}
}
public BaseClass : ITemplate
{
public void myFunction1()
{
Worker worker = new Worker();
worker.DoSomeWork(this);
}
public bool DoSomething(string a)
{
//Some code here
}
}
public DerivedClass : BaseClass
{
public void myFunction2()
{
Worker worker = new Worker();
worker.DoSomeWork(this);
}
}

Method Overloading or method overriding?

In my C# application i have a base class, which contains a function Myfunction.
I have a derived class from the above base class which also contains the same function as in base class, is this concept is correct implementation?
public class BaseClass
{
public void MyFunction()
{
Console.WriteLine("");
}
}
public class DerivedClass:BaseClass
{
public void MyFunction()
{
Console.WriteLine("");
}
}
i am a newbee in Programing , sorry for my english
You've actually hidden BaseClass.MyFunction by doing it that way.
If you want to override properly, you must declare the base version as virtual (or abstract) and then specify override:
public class BaseClass
{
public virtual void MyFunction() { }
}
public class DerivedClass:BaseClass
{
public override void MyFunction() { }
}
Overloading and overriding are different things. The above shows overriding. Overloading refers to when there are multiple methods with the same name, but different parameters. E.g. if you have these methods:
public void MyFunction(int i) {}
public void MyFunction(decimal d) {}
You would say that there are two overloads of MyFunction.
No, this is wrong implementation for method overloading.
If you create a method with same name, and same parameters then it will be method overriding.
If you create a method with same name, but different parameters then it will be method overloading.
If you need to implement your example for method overriding, then add a override keyword on your derived class method and add a virtual keyword with your base class method:
public class BaseClass
{
public virtual void MyFunction()
{
Console.WriteLine("");
}
}
public class DerivedClass:BaseClass
{
public override void MyFunction()
{
Console.WriteLine("");
}
}
If you want to implement an example of overloading, then you will just have to change the parameters of your both methods. Change means they must be different from each other. e.g. :
public class BaseClass
{
public void MyFunction()
{
Console.WriteLine("");
}
}
public class DerivedClass:BaseClass
{
public void MyFunction(string input)
{
Console.WriteLine("");
}
}
In this example, MyFunction in DerivedClass overrides MyFunction in BaseClass.
If you had another MyFunction, this time 'MyFunction(int parameter)', you would have overloaded MyFunction.
You must overload/overrieds methods in this way
public class derived_Class : mybaseclass
{
public override void mymethod()
{
// IF you want to call the base class function as well then you call base.mymethod() ;
base.mymethod();
}
}
class mybaseclass
{
// When you want to overide a method , you must use Virtual keyword
public virtual void mymethod()
{
}
// This is an overload of overload_method
// when you write many methods from same name with different arguments, it's an overload of the method
public void overload_method()
{
}
public void overload_method(string m)
{
}
// When you use an overload
public void use()
{
overload_method();
overload_method(null);
}
}

C# How to execute code after object construction (postconstruction)

As you can see in the code below, the DoStuff() method is getting called before the Init() one during the construction of a Child object.
I'm in a situation where I have numerous child classes. Therefore, repeating a call to the DoStuff() method directly after Init() in the constructor of each child wouldn't be an elegant solution.
Is there any way I could create some kind of post constructor in the parent class that would be executed after the child's constructor? This way, I could call to the DoStuff() method there.
If you have any other design idea which could solve my problem, I'd like to hear it too!
abstract class Parent
{
public Parent()
{
DoStuff();
}
protected abstract void DoStuff();
}
class Child : Parent
{
public Child()
// DoStuff is called here before Init
// because of the preconstruction
{
Init();
}
private void Init()
{
// needs to be called before doing stuff
}
protected override void DoStuff()
{
// stuff
}
}
If you have a complex logic for constructing your objects then consider FactoryMethod pattern.
In your case I would implement it as a simple
public static Parent Construct(someParam)
method that takes some parameter and based on it decides which child class to instantiate.
You can remove your DoStuff() method call from the constructor and call it inside Construct() on the new instance.
Also, you should avoid virtual/abstract method calls in the constructors. See this question for more details: Virtual member call in a constructor
Let me introduce a general solution using some C# features. Note that this solution does not require you to use a factory pattern or invoke anything after constructing the object, and it works on any class with just implementing an interface with a single method.
First we declare an interface that our classes will have to implement:
public interface IInitialize {
void OnInitialize();
}
Next we add a static extension class for this interface, and add the Initialize method:
public static class InitializeExtensions
{
public static void Initialize<T>(this T obj) where T: IInitialize
{
if (obj.GetType() == typeof(T))
obj.OnInitialize();
}
}
Now, if we need a class and all of its descendants to call an initializer right after the object is fully constructed, all we need to do is implement IInitialize and append a line in the constructor:
public class Parent : IInitialize
{
public virtual void OnInitialize()
{
Console.WriteLine("Parent");
}
public Parent()
{
this.Initialize();
}
}
public class Child : Parent
{
public Child()
{
this.Initialize();
}
public override void OnInitialize()
{
Console.WriteLine("Child");
}
}
public class GrandChild : Child
{
public GrandChild()
{
this.Initialize();
}
public override void OnInitialize()
{
Console.WriteLine("GrandChild");
}
}
The trick is that when a derived class calls the extension method Initialize, that will suppress any calls not made from the actual class.
How about this:
abstract class Parent
{
public Parent()
{
Init();
DoStuff();
}
protected abstract void DoStuff();
protected abstract void Init();
}
class Child : Parent
{
public Child()
{
}
protected override void Init()
{
// needs to be called before doing stuff
}
protected override void DoStuff()
{
// stuff
}
}
As others have mentioned, you should use a Factory Pattern.
public class Parent
{
public Parent()
{
}
public virtual void PostConstructor()
{
}
}
public class Child : Parent
{
public override void PostConstructor()
{
base.PostConstructor();
// Your code here
}
}
public void FactoryMethod<T>() where T : Parent
{
T newobject = new T();
newobject.PostConstructor();
}
I would strongly suggest use Factory like a pattern.
If it's possible:
1. Push all your childs and abstract class into separate assembly.
2. Declare ctors of childs like internal methods, so no one out of that assembly is can construct them just by calling ctor.
3. Implement the Factory class to construct for caller specified objects type, which obviuoly will forse calling of abstract DoStuff() method after actual creation of anobject, but before returning it to caller.
Good thing about this is that: It will give you also additional level of abstraction, so if in the future you will need some more functions call or any other type of logical complexity, what you will need, is just add them into your Factory class.
That is.
Regards
In WPF applications, you can postpone the invokation of DoStuff() with the help of Dispatcher:
abstract class Parent
{
public Parent()
{
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(this.DoStuff));
}
private void DoStuff()
{
// stuff, could also be abstract or virtual
}
}
However, it is not guaranteed that DoStuff() will be called immediately after the constructor.
Correction: As per this answer, you can't determine when the base class's constructor is invoked during construction of the subclass.
E.g. This doesn't work:
public Child()
// DoStuff is called here after Init
// because of the overridden default constructor
{
Init();
base();
}
So, yes, as others have noted, if sequence of events matters, then the base class needs to be able to accommodate that by declaring abstract methods in order, or (better yet) by having the child class's implementation of DoStuff represent the sequence of events:
protected override void DoStuff()
{
Init();
base.DoStuff();
}
DoStuff is abstract. Just call Init from the top of DoStuff.
class MyBase
{
public MyBase()
{
//... do something
// finally call post constructor
PostConstructor<MyBase>();
}
public void PostConstructor<T>( )
{
// check
if (GetType() != typeof(T))
return;
// info
System.Diagnostics.Debug.WriteLine("Post constructor : " + GetType());
}
}
class MyChild : MyBase
{
public MyChild()
{
// ... do something
// ... call post constructor
PostConstructor<MyChild>();
}
}
How about...
public MyClass()
{
Dispatcher.UIThread.Post(RunAfterConstructor);
}
I also tried with Task.Run but that didn't work reliably.
Rather than using an abstract method, which would require you to implement the method in all descendant classes, you might try:
public class Parent
{
public Parent()
{
PostConstructor();
}
protected virtual void PostConstructor()
{
}
}
public class Child : Parent
{
protected override void PostConstructor()
{
base.PostConstructor();
/// do whatever initialization here that you require
}
}
public class ChildWithoutOverride
{
/// not necessary to override PostConstructor
}

Categories