简体   繁体   English

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

[英]Reference to object in parent scope in C# - is it possible?

I have a class which creates a "data-holder" object, and then modify this object with some modifier classes, similar to this: 我有一个创建“数据持有者”对象的类,然后使用一些类似于以下内容的修饰符类来修改该对象:

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.
}

In this code, each modification constructor must receive dataHolder as a parameter, with corresponding boilerplate, duplicated code in the modifier classes. 在此代码中,每个修改构造函数必须接收dataHolder作为参数,并且在修改器类中具有对应的样板重复代码。

So I would like, if possible and/or recommended, that each modificator object would "already know" about the existence of the living dataHolder object inside Process.Run() method (its "parent scope", so to say), with no need to pass it as a parameter to the modifier constructors. 因此,我希望,如果可能和/或建议,每个dataHolder对象将“已经知道” Process.Run()方法(可以说是其“父范围” Process.Run()存在的dataHolder对象的存在,而没有需要将其作为参数传递给修饰符构造函数。

EDIT: I am trying to implement the Pipeline (aka Pipes and Filters) design-pattern, inspired in what is described here and here . 编辑:我正在尝试实现管道(又名管道和过滤器)设计模式,灵感来自此处此处所述

Thanks for any help! 谢谢你的帮助!

So I would like, if possible and/or recommended, that each modificator object would "already know" about the existence of the living dataHolder object inside Process.Run() method (its "parent scope", so to say), with no need to pass it as a parameter to the modifier constructors. 因此,我希望,如果可能和/或建议,每个修饰符对象将“已经知道” Process.Run()方法(可以说是其“父范围”)中存在的dataHolder对象的存在,而没有需要将其作为参数传递给修饰符构造函数。

Possible? 可能? Yes, via a thread-local variable to maintain "the current DataHolder for this thread" (or just a simple static variable, even). 是的,通过线程局部变量来维护“该线程的当前DataHolder ”(或者甚至是一个简单的静态变量)。

Recommended? 推荐的? No, I wouldn't say so. 不,我不会这么说。 I see nothing wrong with you've got at the moment - what advantage do you think you would gain from making everything implicit? 我认为您目前没有任何问题-将所有内容隐含起来会带来什么好处?

There's nothing which allows you to go back up the stack and find local variables in the calling method though... 但是没有什么可以让您返回堆栈并在调用方法中找到局部变量的...

You have to somehow associate the instances 您必须以某种方式关联实例

var firstModification = new FirstModification()

etc. with the actual data. 等与实际数据。

The current approach is not a bad one. 当前的方法还不错。 If you want your modification instances to have access to "parent scope", then you would have to pass the parent object reference into them. 如果希望修改实例可以访问“父范围”,则必须将父对象引用传递给它们。 That actually provides them with more access to the parent object than they actually need, which I would discourage. 这实际上为他们提供了对父对象的超出其实际需要的访问权限,我不鼓励这样做。

Use the ref keyword for your parameter. 使用ref关键字作为参数。

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

This will pass a reference to the dataHolder object from the Process class to your FirstModification method. 这会将对dataHolder对象的引用从Process类传递到FirstModification方法。

How about superclassing the Modifier classes and making the DataHolder object available from the Process class as a static variable? 如何超类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...
    {
    }
}

Another option would be to look at inversion of control through frameworks such as MEF and Unity (google those terms). 另一个选择是通过诸如MEF和Unity(用谷歌的术语)之类的框架来研究控制的反转。 What these allow you to do in essence is to register objects which can be automatically loaded when instantiating new classes that have them as a parameter. 这些本质上允许您执行的操作是注册在实例化将其作为参数的新类时可以自动加载的对象。 You're going to say "well, if someone ever needs a DataHolder object, use this one" When you instantiate the modification classes through such frameworks, the 'container' as it's called actually resolves the parameter by asking if it's been registered and taking the registered instance. 您将说:“好吧,如果有人需要DataHolder对象,请使用该对象。”当您通过此类框架实例化修改类时,被称为“容器”的实际上是通过询问参数是否已注册并获取该参数来解析该参数。已注册的实例。

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

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