1

I have a class that I would like to instantiate. It contains two fields, one is a String, and the other is a Action.

Within the action statement, I would like to use the string field in my class. However, I do not know how to directly call it while instantiating. Is there any way, or will I have to create a field to contain the instantiated class, and then call text?

public class ExampleClass
{
    public string text;
    public Action action;
    // on class instantiate -> action.Invoke();
}

public class Program
{
    static void Main(string[] args)
    {
        new ExampleClass
        {
            text = "Hello",
            action = () => { 
                 /* use the text element we specified to do something -> 
                    e.g Console.WriteLine(text); */ },
        };
        Console.ReadLine();
    }
}

Trying to just use text field (like action => ()=> {Console.WriteLine(text);}) results in error:

CS0103 The name 'text' does not exist in the current context

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Kontorted
  • 226
  • 1
  • 13
  • 2
    if you don't put in a variable then it is lost in memory and we don't have handle to that memory location – Ehsan Sajjad Mar 17 '18 at 17:45
  • Side note: "on class instantiate -> action.Invoke()" - you do know that initializer syntax equivalent to setting properties *after* call to constructor, don't you? – Alexei Levenkov Mar 17 '18 at 17:54

1 Answers1

3

You can't. The problem is, this is effectively a closure. You don't have access to the this of the instance you're creating in this manner so you need to "close" over it.

The this you have access to is actually the class which you're writing the code in. In this case, you don't have one because you're in a static function anyway.

using System;

public class ExampleClass
{
    public string text;
    public Action action;
}


public class Program
{
    public static void Main()
    {
        var instance = new ExampleClass
        {
            text = "Hello"
        };
        instance.action = () => Console.WriteLine(instance.text);
        instance.action();
    }
}
McAden
  • 13,714
  • 5
  • 37
  • 63