简体   繁体   English

是否存在用于创建具有受保护成员访问权限的工人类的标准模式?

[英]Is there a standard pattern for creating worker classes with access to protected members?

I just did something kind of wacky using a partial class and I'm wondering if there's an already established pattern that might have accomplished the same thing using a less confusing approach. 我只是使用部分类做了一些古怪的事,我想知道是否存在一种已经建立的模式,使用一种不太混乱的方法可以完成相同的事情。

The problem: 问题:

  • I had a base class with protected members and virtual methods designed for the derived class to do work when they are called. 我有一个带有受保护成员的基类和为派生类设计的虚拟方法,这些派生类在调用它们时可以工作。

  • I wanted to delegate this work out to a list of workers. 我想将这项工作委托给工人名单。

  • However I needed the workers to have access to the protected members. 但是,我需要工人访问受保护的成员。

My probably overly complicated solution: 我可能过于复杂的解决方案:

Note: I realize this depends on the class being partial - I'm OK with that but it would be cool if there was a solution that didn't need it... 注意:我意识到这取决于类的局部性-我可以,但是如果有不需要它的解决方案,那将很酷...

void Main()
{
    ABase aBase = new ADerived();
    aBase.DoWork();
}

public partial class ABase
{
    protected int state1 = 1;
    protected int state2 = 2;
    List<ABase> workers;

    public ABase()
    {
        workers = new List<ABase>();
        CreateWorkers(workers);
    }

    protected virtual void CreateWorkers(List<ABase> workers)
    {
    }

    public ABase(ABase aBase)
    {
        this.Target = aBase;
    }

    public virtual void DoWork()
    {
        foreach (var worker in this.workers)
        {
            worker.DoWork();
        }
    }

    protected ABase Target { get; private set; }
}

public partial class ABase
{
    public class Worker1 : ABase
    {
        public Worker1(ABase aBase) : base(aBase) { }

        public override void DoWork()
        {
            Console.WriteLine (Target.state1);
        }
    }

    public class Worker2 : ABase
    {
        public Worker2(ABase aBase) : base(aBase) { }

        public override void DoWork()
        {
            Console.WriteLine (Target.state2);
        }
    }
}

public class ADerived : ABase
{
    protected override void CreateWorkers(List<ABase> workers) 
    {
        workers.Add(new Worker1(this));
        workers.Add(new Worker2(this));
    }
}

Output: 输出:

1
2

I would change the design so that the workers weren't accessing instance fields at all. 我将更改设计,以使工作人员根本不会访问实例字段。 I would have DoWork take a parameter with the information that they need and have the base class pass the state into the DoWork method. 我希望DoWork接受一个包含他们所需信息的参数,并让基类将状态传递给DoWork方法。

public class MyState //TODO give better name
{
    public int State1 { get; set; }
    public int State2 { get; set; }
}

public class ABase
{
    public MyState state = new MyState()
    {
        State1 = 1,
        State2 = 2
    };

    List<Action<MyState>> workers = new List<Action<MyState>>();

    public ABase()
    {
        CreateWorkers();
    }

    public void DoWork()
    {
        foreach (var action in workers)
        {
            action(state);
        }
    }

    private void CreateWorkers()
    {
        workers.Add(new Worker1().DoWork);
        workers.Add(Worker2.Process);
    }
}

public class Worker1
{
    public void DoWork(MyState state)
    {
        Console.WriteLine(state.State1);
    }
}

public class Worker2
{
    public static void Process(MyState state)
    {
        Console.WriteLine(state.State2);
    }
}

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

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