引用C#中父作用域中的对象是可能的

本文关键字:对象 作用域 引用 | 更新日期: 2023-09-27 18:00:42

我有一个类,它创建了一个"数据持有者"对象,然后用一些修饰符类修改这个对象,类似于:

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作为参数,以及相应的样板,在修改器类中重复代码。

因此,如果可能和/或建议的话,我希望每个修饰符对象都"已经知道"Process.Run()方法(可以说是其"父作用域")中存在活动的dataHolder对象,而无需将其作为参数传递给修饰符构造函数。

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

谢谢你的帮助!

引用C#中父作用域中的对象是可能的

因此,如果可能和/或建议的话,我希望每个修饰符对象都"已经知道"Process.Run()方法(可以说是其"父作用域")中存在活动的dataHolder对象,而无需将其作为参数传递给修饰符构造函数。

可能吗?是的,通过线程本地变量来维护"该线程的当前DataHolder"(甚至只是一个简单的静态变量)。

推荐?不,我不会这么说。我认为你现在没有错——你认为把一切都隐含起来会有什么好处?

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

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

var firstModification = new FirstModification()

等等。与实际数据进行比较。

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

如何对Modifier类进行超类化,并使DataHolder对象作为静态变量从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对象,就用这个"。当你通过这样的框架实例化修改类时,它所调用的"容器"实际上通过询问它是否已经注册并获取注册的实例来解析参数。

使用ref关键字作为参数。

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

这将把对Process类中dataHolder对象的引用传递给FirstModification方法。