在C#中引用父作用域中的对象 - 是否可能?

时间:2013-02-22 20:18:03

标签: c# reference scope

我有一个班级,可以创建一个"数据持有者"对象,然后使用一些修饰符类修改此对象,类似于:

public class Process {
    public void Run() {
        var dataHolder = new DataHolder();

        var firstModification = new FirstModification(dataHolder);
        firstModification.Run();

        var secondModification = new SecondModification(dataHolder);
        secondModification.Run();

        //etc.
    }
}

public class FirstModification {

    DataHolder data_holder;

    public FirstModification (DataHolder dh) {
        data_holder = dh;
    }

    public void Run() {
        // do something with data_holder
    }
}

public class SecondModification {
    // etc.
}

在此代码中,每个修改构造函数必须接收dataHolder作为参数,并在修饰符类中包含相应的样板文件和重复代码。

所以我希望,如果可能和/或推荐,每个修饰符对象都会已经知道"关于dataHolder方法中存在的Process.Run()对象的存在(它的"父范围",可以这么说),不需要将它作为参数传递给修饰符构造函数。

编辑:我正在尝试实现管道(又名管道和过滤器)设计模式,灵感来自所描述的herehere

感谢您的帮助!

4 个答案:

答案 0 :(得分:3)

  

所以我希望,如果可能和/或推荐,每个modificator对象都“已经知道”Process.Run()方法中存在的生命dataHolder对象(其“父范围”,可以这么说) ,无需将其作为参数传递给修饰符构造函数。

可能?是的,通过线程局部变量来维护“此线程的当前DataHolder”(或者只是一个简单的静态变量)。

推荐?不,我不会这么说。我认为你现在没有任何问题 - 你认为通过隐瞒一切会有什么好处?

没有什么可以让你回到堆栈并在调用方法中找到局部变量...

答案 1 :(得分:1)

您必须以某种方式关联实例

var firstModification = new FirstModification()

等。与实际数据。

目前的方法并不错。如果希望修改实例能够访问“父作用域”,则必须将父对象引用传递给它们。这实际上为他们提供了比实际需要更多的父对象访问权限,我不鼓励这样做。

答案 2 :(得分:0)

使用ref关键字作为参数。

...
var firstModification = new FirstModification(ref dataHolder);
...
public FirstModification (ref dataHolder dh) {
    // Make changes to dh
}
...

这会将对DataHolder对象的引用从Process类传递给FirstModification方法。

答案 3 :(得分:0)

如何对Modifier类进行超类并将ProcessHolder对象作为静态变量从Process类中获取?

public class SuperModifierClass
{
    DataHolder dataHolder;

    public SuperModifierClass()
    {
        dataHolder = Process.DataHolder;
    }
}

public class FirstModifier
{
    public FirstModifier() : base() // Is base called implicitly by default? I forgot...
    {
    }
}

另一种选择是通过MEF和Unity等框架来查看控制反转(谷歌那些条款)。这些允许您实际上做的是注册在实例化将它们作为参数的新类时可以自动加载的对象。你会说“好吧,如果有人需要DataHolder对象,请使用这个”当你通过这样的框架实例化修改类时,调用它的'容器'实际上通过询问它是否已经注册并取走来解析参数注册实例。