Assigning code to a variable

C#Variables

C# Problem Overview


Is it possible to make a variable, and assign a line of code to it, such as:

ButtonClicked = (MessageBox.Show("Hello, World!"));

... so when I use the variable, it will execute the line of code.

C# Solutions


Solution 1 - C#

You could assign it to an Action like this:

var ButtonClicked = new Action(() => MessageBox.Show("hi"));

Then call it:

ButtonClicked();

For completeness (in regards to the various comments)...

As Erik stated, you could execute multiple lines of code:

var ButtonClicked = new Action(() =>
{
    MessageBox.Show("hi");

    MessageBox.Show("something else");  // something more useful than another popup ;)
});

As Tim stated, you could omit the Action keyword

Action ButtonClicked = () => MessageBox.Show("hi");

Action ButtonClicked = () =>
{
    // multiple lines of code
};

To address KRyan's comment, regarding the empty parentheses, that represents the list of parameters you want to be able to send to the Action (in this case, none).

If, for instance, you wanted to specify the message to show, you could add "message" as a parameter (note that I changed Action to Action<string> in order to specify a single string parameter):

Action<string> ButtonClicked = (message) => MessageBox.Show(message);

ButtonClicked("hello world!");

Solution 2 - C#

In your case, you want to use a delegate.

Let's see how a delegate works and how we can get to an easier form by understanding its concept:

// Create a normal function
void OnButtonClick()
{
    MessageBox.Show("Hello World!");
}
// Now we create a delegate called ButtonClick
delegate void ButtonClick();

You see, the delegate takes the form of a normal function but without any arguments (It could take any amount of arguments just like any other method, but for the sake of simplicity, it doesn't).

Now, let's use what we have; we will define the delegate just as we define any other variable:

ButtonClick ButtonClicked = new ButtonClick(OnButtonClick);

We basically created a new variable called ButtonClicked, that has a type of ButtonClick (which is a delegate) and that when used, will execute the method in the OnButtonClick() method.
To use it we simply call: ButtonClicked();

So the whole code would be:

delegate void ButtonClick();

void OnButtonClick()
{
    MessageBox.Show("Hello World!");
}

void Foo()
{
    ButtonClick ButtonClicked = new ButtonClick(OnButtonClick);
    ButtonClicked(); // Execute the function.
}  

From here, we can move to lambda expressions and see how they could be useful in your situation:
There are many delegates already defined by .NET libraries, with some like Action, which do not accept any parameter and does no return a value. It is defined as public delegate void Action();
You can always use it to your needs instead of the need of defining a new delegate every time. In the previous context for example, you could had just written

Action ButtonClicked = new Action(OnButtonClick);
ButtonClicked();

which would had done the same.
Now that you saw different ways of how to use delegates, let's use our first lambda expression. Lambda expressions are anonymous functions; so, they are normal functions but without a name. They are of those forms:

x => DoSomethingWithX(x);
(x) => DoSomethingWithX(x);
(x,y) => DoSometingWithXY(x,y);
() => Console.WriteLine("I do not have parameters!");

In our case, we do not have any parameters so we will use the last expression. We can use this just as the OnButtonClick function, but we get the advantage of not having a named function. We can instead do something like this:

Action ButtonClicked = new Action( () => MessageBox.Show("Hello World!") );

or even easier,

Action ButtonClicked = () => MessageBox.Show("Hello World!");

then simply call ButtonClicked(); Of course you can also have multi-lines of code, but I do not want to confuse you more. It would look like this though:

Action ButtonClicked = () => 
{
    MessageBox.Show("Hello World!");
};
ButtonClicked();

You could also play around, for example, you can execute a function like this:

new Action(() => MessageBox.Show("Hello World!"))();

Sorry for the long post, hope it was not too confusing :)

EDIT: I forgot to mention that an alternate form which, even though not often used, could make lambda expressions easier to understand:

new Action(delegate() {
    Console.WriteLine("I am parameterless");
})();

Also, using generics:

// Defines a delegate that has one parameter of type string. You could pass as many parameters as you want.
new Action<string>(delegate(string x) {
    Console.WriteLine(x);
})("I am a string parameter!");

In turn you could use lambda expressions, but you do not need (but might in some cases) to define the type of the parameter, for example, the code above could simply be written as:

new Action<string>(x => {
    Console.WriteLine(x);
})("I am a string parameter!");

or:

new Action<string>(x => Console.WriteLine(x))("I am a string parameter!");

EDIT2:
Action<string> is a representation of public void delegate Action(string obj);
Action<string,string> is a representation of public void delegate Action(string obj, string obj2);
In general, Action<T> is a representation of public void delegate Action<T>(T obj);

EDIT3: I know the post has been here for a while, but I think this is really cool to not mention: You can do this, which is mostly related to your question:

dynamic aFunction = (Func<string, DialogResult>)MessageBox.Show;
aFunction("Hello, world!");

or simply:

Func<string, DialogResult> aFunction = MessageBox.Show;
aFunction("Hello, world!");

Solution 3 - C#

The Lazy class is specifically designed to represent a value that won't be computed until you ask for it. You construct it by providing a method that defines how it should be constructed, but it will handle executing that method no more than once (even in the face of multiple threads requesting the value) and simply returning the already constructed value for any additional requests:

var foo = new Lazy<DialogResult>(()=>MessageBox.Show("Hello, World!"));

var result = foo.Value;

Solution 4 - C#

The way I'm reading your question, this is in the context of GUI controls?

If this is in WPF, take a look at the "right" way to handle commands from controls: http://msdn.microsoft.com/en-us/library/ms752308(v=vs.110).aspx

...but that can be a pain and overkill. For a simpler general case, you might be looking for an event handler, like:

myButton.Click += (o, e) => MessageBox.Show("Hello, World!");

That event handler can be handled a variety of ways. The above example uses an anonymous function, but you could also do:

Action<object, RoutedEventArgs> sayHello = (o, e) => MessageBox.Show("Hello, World");
myButton.Click += new RoutedEventHandler(sayHello);

...just like you were asking, with a function (or here, "Action", since it returns void) assigned as a variable.

Solution 5 - C#

You can assign C# code to a variable, compiling it at runtime and run the code:

  • Write your code:

      // Assign C# code to the code variable.
      string code = @"
      using System;
    
      namespace First
      {
          public class Program
          {
              public static void Main()
              {
                  " +
                  "Console.WriteLine(\"Hello, world!\");"
                  + @"
              }
          }
      }
      ";
    
  • Create the provider and parameters of the compiler:

      CSharpCodeProvider provider = new CSharpCodeProvider();
      CompilerParameters parameters = new CompilerParameters();
    
  • Define parameters of the compiler:

      // Reference to System.Drawing library
      parameters.ReferencedAssemblies.Add("System.Drawing.dll");
      // True - memory generation, false - external file generation
      parameters.GenerateInMemory = true;
      // True - exe file generation, false - dll file generation
      parameters.GenerateExecutable = true;
    
  • Compile assembly:

      CompilerResults results = provider.CompileAssemblyFromSource(parameters, code);
    
  • Check errors:

      if (results.Errors.HasErrors)
      {
              StringBuilder sb = new StringBuilder();
    
              foreach (CompilerError error in results.Errors)
              {
                      sb.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText));
              }
    
              throw new InvalidOperationException(sb.ToString());
      }
    
  • Get assembly, type and the Main method:

      Assembly assembly = results.CompiledAssembly;
      Type program = assembly.GetType("First.Program");
      MethodInfo main = program.GetMethod("Main");
    
  • Run it:

      main.Invoke(null, null);
    

Reference:

http://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3539891View Question on Stackoverflow
Solution 1 - C#Grant WinneyView Answer on Stackoverflow
Solution 2 - C#user3439065View Answer on Stackoverflow
Solution 3 - C#ServyView Answer on Stackoverflow
Solution 4 - C#ZacconeView Answer on Stackoverflow
Solution 5 - C#Amir SaniyanView Answer on Stackoverflow