简体   繁体   中英

How Do I capture a variable (C#)

How Do I capture a variable?
Alternatively, can I store a reference to an object reference?

Normally, a method can alter a variable outside of it using ref keyword.

void Foo(ref int x)
{
    x = 5;
}

void Bar()
{
    int m = 0;
    Foo(ref m);
}

This is clear and straight-forward.

Now let's consider a class to achieve the same thing:

class Job
{
    // ref int _VarOutsideOfClass; // ?????

    public void Execute()
    {
        // _VarOutsideOfClass = 5; // ?????
    }
}

void Bar()
{
    int m = 0;
    var job = new Job()
    {
        _VarOutsideOfClass = ref m    // How ?
    };
    job.Execute();
}

How do I write it correctly ?


Comments: I can't make it a method with an ref argument, because typically Execute() will called somewhat later in a different thread, when it comes up in the queue.

Currently, I made a prototype with plenty of lambdas:

class Job
{
    public Func<int> InParameter;
    public Action<int> OnResult;

    public void Execute()
    {
        int x = InParameter();
        OnResult(5);
    }
}

void Bar()
{
    int m = 0;
    var job = new Job()
    {
        InParameter = () => m,
        OnResult = (res) => m = res
    };
    job.Execute();
}

... but maybe there is a better idea.

You can't have a ref field. See, for example, http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx (scroll down to where it says "This explains why you cannot make a “ref int” field....").

A lambda or a delegate is probably your best bet here. I suppose you could use an event, or an observer interface, or something.

Use Array with 1 element

class Job{
int[] _VarOutsideOfClass = new int[1];

Also You can use wrapper "int?" - forgive them nullable, but remember that it always passed over reference.

Here's a guess (I haven't tried/tested it):

class Job
{
  Action<int> m_delegate;

  public Job(ref int x)
  {
    m_delegate = delegate(int newValue)
    {
      x = newValue;
    };
  }

  public void Execute()
  {
    //set the passed-in varaible to 5, via the anonymous delegate
    m_delegate(5);
  }
}

If the above doesn't work, then say that the Job constructor takes a delegate as its parameter, and construct the delegate inside the Bar class (and pass the delegate instead of passing the ref parameter).

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.

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