C# 将代码赋给变量
是否可以生成一个变量,并为其分配一行代码,例如:C# 将代码赋给变量,c#,variables,C#,Variables,是否可以生成一个变量,并为其分配一行代码,例如: ButtonClicked = (MessageBox.Show("Hello, World!")); 。。。因此,当我使用该变量时,它将执行代码行。您可以将其分配给如下类型的: var ButtonClicked = new Action(() => MessageBox.Show("hi")); Action ButtonClicked = new Action( () => MessageBox.Show("Hello Wo
ButtonClicked = (MessageBox.Show("Hello, World!"));
。。。因此,当我使用该变量时,它将执行代码行。您可以将其分配给如下类型的:
var ButtonClicked = new Action(() => MessageBox.Show("hi"));
Action ButtonClicked = new Action( () => MessageBox.Show("Hello World!") );
new Action(() => MessageBox.Show("Hello World!"))();
那就叫它:
ButtonClicked();
为了完整性(关于各种评论)
正如Erik所说,您可以执行多行代码:
var ButtonClicked = new Action(() =>
{
MessageBox.Show("hi");
MessageBox.Show("something else"); // something more useful than another popup ;)
});
正如Tim所说,您可以省略操作
关键字
Action ButtonClicked = () => MessageBox.Show("hi");
Action ButtonClicked = () =>
{
// multiple lines of code
};
为了回应KRyan关于空括号的评论,它表示您希望能够发送到操作的参数列表(在本例中,无)
例如,如果您想指定要显示的消息,可以添加“message”作为参数(注意,为了指定单个字符串参数,我将Action
更改为):
Action按钮点击=(消息)=>MessageBox.Show(消息);
按钮点击(“你好,世界!”);
该类专门设计用于表示一个值,该值在您要求时才会计算。您可以通过提供一个方法来构造它,该方法定义了应该如何构造它,但它将处理执行该方法不超过一次(即使在多个线程请求该值的情况下)并简单地为任何其他请求返回已构造的值:
var foo = new Lazy<DialogResult>(()=>MessageBox.Show("Hello, World!"));
var result = foo.Value;
var foo=newlazy(()=>MessageBox.Show(“你好,世界!”);
var结果=foo.Value;
按照我理解您问题的方式,这是在GUI控件的上下文中
如果是在WPF中,请查看处理控件命令的“正确”方法:
…但这可能是一种痛苦和过度的杀伤力。对于更简单的一般情况,您可能需要一个事件处理程序,如:
myButton.Click += (o, e) => MessageBox.Show("Hello, World!");
可以通过多种方式处理该事件处理程序。上述示例使用匿名函数,但您也可以执行以下操作:
Action<object, RoutedEventArgs> sayHello = (o, e) => MessageBox.Show("Hello, World");
myButton.Click += new RoutedEventHandler(sayHello);
Action sayHello=(o,e)=>MessageBox.Show(“你好,世界”);
myButton.Click+=新建路由EventHandler(说你好);
…就像您所问的那样,将函数(或此处的“Action”,因为它返回void)指定为变量。在您的情况下,您希望使用
委托
让我们看看代理是如何工作的,以及我们如何通过理解其概念来获得更简单的形式:
// Create a normal function
void OnButtonClick()
{
MessageBox.Show("Hello World!");
}
// Now we create a delegate called ButtonClick
delegate void ButtonClick();
你看,委托采用普通函数的形式,但没有任何参数(它可以像任何其他方法一样采用任意数量的参数,但为了简单起见,它没有)
现在,让我们利用我们所拥有的;我们将定义委托,就像定义任何其他变量一样:
ButtonClick ButtonClicked = new ButtonClick(OnButtonClick);
我们基本上创建了一个名为ButtonClick的新变量,该变量有一种ButtonClick类型(委托),使用时将在OnButtonClick()方法中执行该方法。要使用它,我们只需调用:
ButtonClicked()代码>
所以整个代码是:
delegate void ButtonClick();
void OnButtonClick()
{
MessageBox.Show("Hello World!");
}
void Foo()
{
ButtonClick ButtonClicked = new ButtonClick(OnButtonClick);
ButtonClicked(); // Execute the function.
}
从这里,我们可以转到lambda表达式,看看它们在您的情况下如何有用:
.NET库已经定义了许多委托,其中有些委托具有类似的操作,它们不接受任何参数,也不返回值。定义为public delegate void Action()代码>
您总是可以根据自己的需要使用它,而不是每次都需要定义一个新的委托。例如,在前面的上下文中,您可以只编写
Action ButtonClicked = new Action(OnButtonClick);
ButtonClicked();
也会这样做。
既然您已经了解了使用委托的不同方法,那么让我们使用第一个lambda表达式。Lambda表达式是匿名函数;因此,它们是普通函数,但没有名称。它们的形式如下:
x => DoSomethingWithX(x);
(x) => DoSomethingWithX(x);
(x,y) => DoSometingWithXY(x,y);
() => Console.WriteLine("I do not have parameters!");
在本例中,我们没有任何参数,因此将使用最后一个表达式。我们可以像使用OnButtonClick函数一样使用它,但是我们没有命名函数的优点。我们可以这样做:
var ButtonClicked = new Action(() => MessageBox.Show("hi"));
Action ButtonClicked = new Action( () => MessageBox.Show("Hello World!") );
new Action(() => MessageBox.Show("Hello World!"))();
甚至更容易
Action ButtonClicked = () => MessageBox.Show("Hello World!");
然后只需调用ButtonClicked()当然你也可以有多行代码,但我不想让你更困惑。但看起来是这样的:
Action ButtonClicked = () =>
{
MessageBox.Show("Hello World!");
};
ButtonClicked();
您也可以玩游戏,例如,您可以执行如下函数:
var ButtonClicked = new Action(() => MessageBox.Show("hi"));
Action ButtonClicked = new Action( () => MessageBox.Show("Hello World!") );
new Action(() => MessageBox.Show("Hello World!"))();
抱歉发了这么长的帖子,希望不要太混乱:)
编辑:我忘了提到另一种形式,即使不经常使用,也可以使lambda表达式更容易理解:
new Action(delegate() {
Console.WriteLine("I am parameterless");
})();
此外,使用泛型:
// 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!");
或者简单地说:
Func<string, DialogResult> aFunction = MessageBox.Show;
aFunction("Hello, world!");
Func affunction=MessageBox.Show;
函数(“你好,世界!”);
您可以将C代码分配给变量,在运行时编译并运行代码:
- 编写代码:
// Assign C# code to the code variable.
string code = @"
using System;
namespace First
{
public class Program
{
public static void Main()
{
" +
"Console.WriteLine(\"Hello, world!\");"
+ @"
}
}
}
";
- 创建编译器的提供程序和参数:
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;
- 定义编译器的参数:
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());
}
- 获取程序集、类型和主要方法:
Assembly assembly = results.CompiledAssembly;
Type program = assembly.GetType("First.Program");
MethodInfo main = program.GetMethod("Main");
- 运行它:
main.Invoke(null, null);
参考:
操作按钮点击=()=>MessageBox.Show(“嗨”)
是等效的,而且我觉得更好(如果您愿意,可以添加参数),操作也可以解析为多行代码。@CSharpie我不确定这样的假设对OP是否有帮助。@CSharpie为什么OP不能在WinForms
中使用此选项?@CSharpie我明白您的意思。如果他真的将其附加到一个按钮上。单击事件,而不是将其存储在一个他碰巧命名为按钮的变量中。单击+1是因为他不熟悉编码并提出了一个好问题,这是一个罕见的组合:你了解你想要做什么,并且解释得很好,你只是不知道它的术语,所以你自己找不到。你要找的术语是一个。看看这个,我想你需要足够的解释。Asp在这方面的工作原理几乎与winforms类似。听起来很像Objective cRemember中的块,即惰性
应用于需要大量处理能力的值,而不应将它们用于交互(因为.Value
的语义是它返回一个值,