변수를 만들고 다음과 같은 코드 줄을 할당 할 수 있습니까?
ButtonClicked = (MessageBox.Show("Hello, World!"));
… 변수를 사용하면 코드 줄이 실행됩니다.
답변
다음 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>
Action<string> ButtonClicked = (message) => MessageBox.Show(message);
ButtonClicked("hello world!");
답변
귀하의 경우에는 delegate
.
대리자가 어떻게 작동하는지 그리고 개념을 이해하여 더 쉬운 양식에 도달하는 방법을 살펴 보겠습니다.
// 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 (대리자) 유형을 갖는 ButtonClicked라는 새 변수를 만들었으며 사용시 OnButtonClick () 메서드에서 메서드를 실행합니다.
이를 사용하려면 다음을 호출하면됩니다.ButtonClicked();
따라서 전체 코드는 다음과 같습니다.
delegate void ButtonClick();
void OnButtonClick()
{
MessageBox.Show("Hello World!");
}
void Foo()
{
ButtonClick ButtonClicked = new ButtonClick(OnButtonClick);
ButtonClicked(); // Execute the function.
}
여기에서 람다 식으로 이동하여 상황에서 유용 할 수있는 방법을 확인할 수 있습니다.
.NET 라이브러리에 의해 이미 정의 된 많은 대리자가 있으며 일부는 매개 변수를 허용하지 않고 값을 반환하지 않는 Action과 같습니다. 과 같이 정의된다 public delegate void Action();
당신은 항상 새로운 위임마다 정의의 필요성 대신 여러분의 필요에 사용할 수 있습니다. 예를 들어 이전 컨텍스트에서 방금 작성했을 수 있습니다.
Action ButtonClicked = new Action(OnButtonClick);
ButtonClicked();
같은 일을했을 것입니다.
이제 대리자를 사용하는 다양한 방법을 보았으므로 첫 번째 람다 식을 사용하겠습니다. Lambda 표현식은 익명 함수입니다. 그래서 그들은 정상적인 기능이지만 이름이 없습니다. 다음과 같은 형태입니다.
x => DoSomethingWithX(x);
(x) => DoSomethingWithX(x);
(x,y) => DoSometingWithXY(x,y);
() => Console.WriteLine("I do not have parameters!");
이 경우에는 매개 변수가 없으므로 마지막 표현식을 사용합니다. 이것을 OnButtonClick 함수로 사용할 수 있지만 명명 된 함수가 없다는 이점이 있습니다. 대신 다음과 같이 할 수 있습니다.
Action ButtonClicked = new Action( () => MessageBox.Show("Hello World!") );
또는 더 쉽게
Action ButtonClicked = () => MessageBox.Show("Hello World!");
그런 다음 단순히 전화하십시오 ButtonClicked();
물론 여러 줄의 코드를 가질 수도 있지만 더 이상 혼동하고 싶지 않습니다. 그래도 다음과 같이 보일 것입니다.
Action ButtonClicked = () =>
{
MessageBox.Show("Hello World!");
};
ButtonClicked();
예를 들어 다음과 같은 함수를 실행할 수도 있습니다.
new Action(() => MessageBox.Show("Hello World!"))();
긴 게시물에 대해 죄송합니다. 너무 혼란스럽지 않았기를 바랍니다. 🙂
편집 : 자주 사용되지는 않지만 람다 식을 더 쉽게 이해할 수있는 대체 형식을 언급하는 것을 잊었습니다.
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!");
차례로 람다 식을 사용할 수 있지만 매개 변수 유형을 정의 할 필요가 없습니다 (경우에 따라 경우도 있음). 예를 들어 위의 코드는 다음과 같이 간단하게 작성할 수 있습니다.
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);
EDIT3 : 게시물이 잠시 여기에 있었다는 것을 알고 있지만 이것은 언급하지 않아도 정말 멋지다고 생각합니다. 대부분의 질문과 관련된이 작업을 수행 할 수 있습니다.
dynamic aFunction = (Func<string, DialogResult>)MessageBox.Show;
aFunction("Hello, world!");
또는 간단히 :
Func<string, DialogResult> aFunction = MessageBox.Show;
aFunction("Hello, world!");
답변
이 Lazy
클래스는 사용자가 요청할 때까지 계산되지 않는 값을 나타내도록 특별히 설계되었습니다. 구성 방법을 정의하는 메서드를 제공하여 구성하지만, 해당 메서드를 한 번만 실행하고 (값을 요청하는 여러 스레드가있는 경우에도) 추가 요청에 대해 이미 구성된 값을 반환합니다.
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를 반환하기 때문에).
답변
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;
-
어셈블리 컴파일 :
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()); }
-
어셈블리, 유형 및 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