I have a child and a parent class in C#. I want to point the Calc delegate to one of several methods. this is determined each time the Reset() method is called. Below is a working example. However, I want this functionality of pointing the delegate to reside on the Parent class. Since the parent does not contain the methods, I don't know how to do it...
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();
}
One way to do that would be to have the Child
class inject its methods into the Parent at construction time. That way, the Parent
class makes the choice, but the Child
class defines the functionality:
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");
}
}
Also, I'd get rid of StateHandler
and just use Action
instead. Don't create a new delegate when a standard one exists already.
While trying to get the answer I liked to work, I managed to solve it in a different way by making the Parent abstract, and it works.
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");
}
}
One way is to move the "Reset" method to the parent class and do something like this:
public void Reset()
{
var child = this as IChild;
if (child != null && Model.Env1)
Calc = child.CalcHeavy;
else
Calc = child.CalcLight;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.