C# 中的委托和继承

发布于 2024-11-28 05:12:40 字数 1407 浏览 1 评论 0原文

我在委托继承方面遇到了一些问题。据我理解,委托是一个指向一对的指针:一个实例和一个方法,问题是这是在创建委托时引用的方法,并且不受继承的影响。所以,这是行不通的:

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 运行基本 Method(),我希望它运行继承的 Method()。我已经找到了一些解决办法,但它效率低下,分散注意力,而且很容易出错,无论如何,这是我想摆脱的当前工作版本:

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();

这种 DoMethod 方法有效,但有很多问题,

  1. 很多无用的代码很
  2. 容易出错使用类 - 容易将 obj.next=DoMethod 与 obj.next=Method
  3. 混淆 在继承类时容易出错 - 我必须记住不要继承 DoMethod,以及大量的虚拟和覆盖。

有什么建议我怎样才能做得更好?也许有一些注释魔法可以让 DoMethod 本身发挥作用?我已经想到了字典 - 它们在这里并不好,它们甚至增加了另一个层次的混乱(Mono、.NET 2、Unity3d 框架)

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,

  1. lots of useless code
  2. error prone when using the class - easy to mistake obj.next=DoMethod with obj.next=Method
  3. 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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谎言月老 2024-12-05 05:12:40

您可以将 next=DoMethod; 替换为 next= ()=>Method(); ,本质上是相同的,但不需要您定义额外的方法在你的课堂上。

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.

尽揽少女心 2024-12-05 05:12:40

在第一个示例中,您将 Method();结果分配给委托,因此自然意味着 Method方法 (ahem) 将在此时执行以分配值。忽略 Methodvoid (无法编译)这一事实。

在第二个示例中,您将分配对该方法的引用(这不会编译) t 必须是实例方法)到委托,这允许您在稍后阶段执行 del

以下内容对我有用:

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");
    }
}

在上面的示例中,委托指针表示为指向(BaseObject)的Something方法的指针,因为该方法是虚拟的,调用仍然正确地分派到重写的 Something 方法(DerivedObject)。

您没有看到相同的行为吗?

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?

深府石板幽径 2024-12-05 05:12:40

不,Execute 将运行继承的方法。对代码进行一些更正后,我可以测试它:

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");
  }

}

调用:

(new InheritedObject()).Execute();

输出:

inherited

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文