将代码分配给一个variables

是否可以创build一个variables,并为其分配一行代码,例如:

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

…所以当我使用variables时,它将执行代码行。

你可以把它分配给这样一个Action

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

然后调用它:

 ButtonClicked(); 

为了完整性(关于各种意见)…

正如Erik所说,你可以执行多行代码:

 var ButtonClicked = new Action(() => { MessageBox.Show("hi"); MessageBox.Show("something else"); // something more useful than another popup ;) }); 

正如Tim所说,你可以省略Action关键字

 Action ButtonClicked = () => MessageBox.Show("hi"); Action ButtonClicked = () => { // multiple lines of code }; 

为了解决KRyan的评论,关于空圆括号,它代表你想要发送给Action的参数列表(在这种情况下,没有)

例如,如果您想要指定要显示的消息,则可以将“message”添加为参数(请注意,我已将 Action 更改 Action<string> 以便指定单个string参数)

 Action<string> ButtonClicked = (message) => MessageBox.Show(message); ButtonClicked("hello world!"); 

在你的情况下,你想使用一个delegate

让我们看看委托人是如何工作的,以及如何通过理解委托人的概念来获得更简单的forms:

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

你看,代表采取正常函数的forms,但没有任何参数(它可以采取任何数量的参数就像任何其他方法,但为了简单起见,它不)。

现在,让我们用我们所拥有的; 我们将定义委托,就像我们定义任何其他variables一样:

 ButtonClick ButtonClicked = new ButtonClick(OnButtonClick); 

我们基本上创build了一个名为ButtonClicked的新variables,它有一个ButtonClicktypes(它是一个委托),使用时将在OnButtonClick()方法中执行该方法。
要使用它,我们只需调用: ButtonClicked();

所以整个代码将是:

 delegate void ButtonClick(); void OnButtonClick() { MessageBox.Show("Hello World!"); } void Foo() { ButtonClick ButtonClicked = new ButtonClick(OnButtonClick); ButtonClicked(); // Execute the function. } 

从这里,我们可以移动到lambdaexpression式,看看它们在你的情况下是如何有用的:
有许多已经由.NET库定义的委托,有些像Action,它们不接受任何参数,也不返回任何值。 它被定义为public delegate void Action();
您可以随时使用它来满足您的需求,而不必每次都定义一个新的委托。 例如,在前面的情况下,你可能已经写了

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

这样做也是一样的。
现在您已经看到了如何使用委托的不同方式,我们使用我们的第一个lambdaexpression式。 Lambdaexpression式是匿名函数; 所以,他们是正常的function,但没有名字。 它们是这些forms:

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

在我们的例子中,我们没有任何参数,所以我们将使用最后一个expression式。 我们可以像OnButtonClick函数一样使用它,但是我们获得了没有命名函数的优点。 我们可以做这样的事情:

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

甚至更容易,

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

然后简单地调用ButtonClicked(); 当然你也可以有多行代码,但我不想让你更困惑。 它会看起来像这样:

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

你也可以玩,例如,你可以执行这样的function:

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

对不起,很长的post,希望它不是太混乱:)

编辑:我忘了提及一个替代forms,即使不经常使用,可以使lambdaexpression式更容易理解:

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

另外,使用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!"); 

反过来,你可以使用lambdaexpression式,但是你不需要(但可能在某些情况下)来定义参数的types,例如,上面的代码可以简单地写成:

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

要么:

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

EDIT2:
Action<string>public void delegate Action(string obj);
Action<string,string>public void delegate Action(string obj, string obj2);
通常, Action<T>public void delegate Action<T>(T obj);

编辑3:我知道这个post在这里已经有一段时间了,但是我觉得这很酷,不要提到:你可以做到这一点,这主要与你的问题有关:

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

或者干脆:

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

Lazy类是专门devise用来表示一个值,直到你要求它才会被计算出来。 通过提供一个定义应该如何构build的方法来构造它,但是它将不会一次(甚至在多个线程请求值的情况下)处理该方法的执行,并简单地返回已经构造的值以用于任何其他请求:

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

我正在阅读你的问题的方式,这是在GUI控件的上下文?

如果这是在WPF中,请看一下“正确”的方式来处理来自控件的命令: http : //msdn.microsoft.com/en-us/library/ms752308(v=vs.110).aspx

…但这可能是一个痛苦和矫枉过正 对于更简单的一般情况,您可能正在寻找一个事件处理程序,如:

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

该事件处理程序可以通过多种方式进行处理。 上面的例子使用了一个匿名函数,但是你也可以这样做:

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

…就像你问的那样,用一个函数(或者这里,“Action”,因为它返回void)被赋值为一个variables。

您可以将C#代码分配给一个variables,在运行时编译它并运行代码:

  • 写下你的代码:

     // Assign C# code to the code variable. string code = @" using System; namespace First { public class Program { public static void Main() { " + "Console.WriteLine(\"Hello, world!\");" + @" } } } "; 
  • 创build编译器的提供者和参数:

     CSharpCodeProvider provider = new CSharpCodeProvider(); CompilerParameters parameters = new CompilerParameters(); 
  • 定义编译器的参数:

     // 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; 
  • 编译汇编:

     CompilerResults results = provider.CompileAssemblyFromSource(parameters, code); 
  • 检查错误:

     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()); } 
  • 获取程序集,types和Main方法:

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

     main.Invoke(null, null); 

参考:

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