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

时间:2015-05-27 09:47:53

标签: c#

我在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();
}

3 个答案:

答案 0 :(得分:1)

这样做的一种方法是让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。当标准存在时,不要创建新的委托。

答案 1 :(得分:1)

在尝试获得我喜欢的答案时,我设法通过制作父抽象以不同的方式解决它,并且它有效。

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

答案 2 :(得分:0)

一种方法是移动"重置"父类的方法,并执行以下操作:

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

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