Delegates and inheritance in 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 con开发者_JAVA技巧fusion (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
精彩评论