繁体   English   中英

使用委托和继承定义哪个方法在子类中运行

[英]Using delegate and inheritance to define which method is run inside the child class

我在C#中有一个孩子和一个父类。 我想将Calc委托指向几种方法之一。 这是在每次调用Reset()方法时确定的。 下面是一个工作示例。 但是,我希望这种指向委托的功能驻留在Parent类上。 由于父级不包含方法,因此我不知道该怎么做...

    class Program
{
    static void Main(string[] args)
    {
        Model Model = new Model();
        Model.Env1 = true;
        Child Ch = new Child(Model);
        Ch.Reset();
        Ch.Calc(); Ch.Calc(); Ch.Calc();
        Console.WriteLine();
        Model.Env1 = false;
        Ch.Reset();
        Ch.Calc(); Ch.Calc(); Ch.Calc();
        Console.ReadLine();
    }
}

public class Parent
{
    public Model Model { get; set; }
    public Parent(Model model)
    {
        Model = model;
    }
    public delegate void StateHandler();
    public StateHandler Calc;
}
public class Model
{
    public bool Env1 { get; set; }
}
public class Child : Parent, IChild
{
    public Child (Model model)
        : base (model)
    {
    }
    public void Reset()
    {
        if (Model.Env1)
            Calc = CalcHeavy;
        else
            Calc = CalcLight;
    }
    public void CalcHeavy()
    {
        Console.WriteLine("CalcHeavy is active");
    }
    public void CalcLight()
    {
        Console.WriteLine("CalcLight is active");
    }
}
public interface IChild
{
    void CalcHeavy();
    void CalcLight();
}

一种实现方法是让Child类在构造时将其方法注入Parent。 这样, Parent类做出选择,而Child类定义功能:

public class Parent
{
    private readonly Action _env1Method;
    private readonly Action _notEnv1Method;
    private readonly Model _model;

    public Parent(Model model, 
                  Action env1Method, 
                  Action notEnv1Method)
    {
        _model = model;
        _env1Method = env1Method;
        _notEnv1Method = notEnv1Method;
        Reset();
    }

    public Action Calc { get; private set; }

    public void Reset()
    {
        Calc = _model.Env1 ? _env1Method : _notEnv1Method;
    }
}

public class Model
{
    public bool Env1 { get; set; }
}

public class Child : Parent
{
    public Child (Model model) : base (model, CalcHeavy, CalcLight) {}

    private static void CalcHeavy()
    {
        Console.WriteLine("CalcHeavy is active");
    }

    private static void CalcLight()
    {
        Console.WriteLine("CalcLight is active");
    }
}

此外,我将摆脱StateHandler而仅使用Action 如果已经存在标准委托,则不要创建新委托。

在尝试获得我喜欢的答案时,我设法通过使Parent抽象化来以不同的方式解决它,并且它起作用了。

    class Program
{
    static void Main(string[] args)
    {
        Model Model = new Model();
        Model.Env1 = true;
        Child Ch = new Child(Model);

        Ch.Calc(); Ch.Calc(); Ch.Calc();
        Console.WriteLine();
        Model.Env1 = false;

        Ch = new Child(Model);
        Ch.Calc(); Ch.Calc(); Ch.Calc();
        Console.ReadLine();
    }
}

public abstract class Parent
{
    public Model Model { get; set; }
    public Parent(Model model)
    {
        Model = model;
        if (Model.Env1)
            Calc = CalcHeavy;
        else
            Calc = CalcLight;
    }

    public Action Calc;

    public abstract void CalcHeavy();
    public abstract void CalcLight();

}
public class Model
{
    public bool Env1 { get; set; }
}
public class Child : Parent
{
    public Child(Model model) : base(model) { }

    public override void CalcHeavy()
    {
        Console.WriteLine("CalcHeavy is active");
    }
    public override void CalcLight()
    {
        Console.WriteLine("CalcLight is active");
    }
}

一种方法是将“ Reset”方法移至父类并执行以下操作:

public void Reset()
{
       var child = this as IChild;

        if (child != null && Model.Env1)
            Calc = child.CalcHeavy;
        else
            Calc = child.CalcLight;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM