在C#中有一种方法可以像jQuery"one"方法一样调用一次方法吗?

Müs*_*sli 9 c#

我想知道是否有一种方法可以在C#中执行一次代码,比如jquery中的"one":

$("#foo").one("click",function(){alert("这将只显示一次.");});

我想做的是以下内容:

public void foo(){
  Console.Write("hello");
}
Run Code Online (Sandbox Code Playgroud)

然后

foo();
foo();
foo();
Run Code Online (Sandbox Code Playgroud)

并且输出结果必须是

hello
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个库而不仅仅是使用flags属性.

Jam*_*iec 16

jQuery示例是一个事件处理程序,一旦调用了事件处理程序,它就会从元素中删除.用于(例如)按钮点击事件的C#中的等价物将是

myButton.Click += new EventHandler(MyEventHandler)

void MyEventHandler(object sender, EventArgs e)
{
  Console.Write("hello");
  ((Button)sender).Click -= new EventHandler(MyEventHandler);
}
Run Code Online (Sandbox Code Playgroud)

这样,只有第一次单击该按钮才会产生Console Write.

  • "通过这种方式,只有第一次点击按钮才会产生控制台写入." - 这不完全正确.如果他有多线程代码或代码,这些代码或代码以任意数量的ad-hoc方式调用,并且在删除处理程序之前可能导致超过1次调用.在方法声明之前添加`[MethodImpl(MethodImplOptions.Synchronized)]`将是解决此问题的一种方法. (2认同)

TcK*_*cKs 13

我无法想象为什么会这样做,但如果你真的这样做,如果你想要任何方法通用,你可以这样做:

void Main() {
    var myFoo = callOnlyOnce(foo);
    myFoo();
    myFoo();
    myFoo();

   var myBar = callOnlyOnce(bar);
   myBar();
   myBar();
   myBar();
}

void foo(){
  Console.Write("hello");
}
void bar() { Console.Write("world"); }


Action callOnlyOnce(Action action){
    var context = new ContextCallOnlyOnce();
    Action ret = ()=>{
        if(false == context.AlreadyCalled){
            action();
            context.AlreadyCalled = true;
        }
    };

    return ret;
}
class ContextCallOnlyOnce{
    public bool AlreadyCalled;
} 
Run Code Online (Sandbox Code Playgroud)


blu*_*oft 8

我知道这是旧新闻......但这里有一个函数式方法来解决这个问题,有人可能会觉得有用:

    public static Action<T> Once<T>(Action<T> action )
    {
        return (arg) =>
        {
            action?.Invoke(arg);
            action = null;
        };
    }
Run Code Online (Sandbox Code Playgroud)

然后你可以生成一个函数,它只完成一次主要工作:

    var writeNumberToConsole = Once<int>( Console.WriteLine );
    writeNumberToConsole(1); // "1"
    writeNumberToConsole(2); -> //nothing
    writeNumberToConsole(3); -> //nothing
Run Code Online (Sandbox Code Playgroud)


Rof*_*ion 6

当你可以做这样的事情时,为什么你想要一个图书馆:

private bool wasExecuted = false;

public void foo(){
  if (!wasExecuted) {
     Console.Write("hello");
     wasExecuted = true;
  }
}
Run Code Online (Sandbox Code Playgroud)