Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中有没有一种方法可以像在jQuery中那样只调用一次方法;“一”;方法?_C# - Fatal编程技术网

C# 在C中有没有一种方法可以像在jQuery中那样只调用一次方法;“一”;方法?

C# 在C中有没有一种方法可以像在jQuery中那样只调用一次方法;“一”;方法?,c#,C#,我想知道是否有一种方法可以在C中只执行一次代码,比如jquery中的“一”: $(#foo”).one(“单击”,函数(){ 警报(“这将只显示一次。”); }); 我想做的是: public void foo(){ Console.Write("hello"); } 然后 并且输出结果必须是 hello 我正在寻找一个库,而不仅仅是使用flags属性。jQuery示例是一个事件处理程序,一旦调用了事件处理程序,它就会从元素中删除。用C#表示(例如)按钮点击事件的等价物是 private

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

$(#foo”).one(“单击”,函数(){ 警报(“这将只显示一次。”); });

我想做的是:

public void foo(){
  Console.Write("hello");
}
然后

并且输出结果必须是

hello

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

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

private bool _fooExecuted = false;

public void foo(){
  if (_fooExecuted)
     return;

  _fooExecuted = true;

  Console.Write("hello");
}
myButton.Click += new EventHandler(MyEventHandler)

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

这样,只需第一次单击按钮,即可生成控制台写入。

我认为您不会为此找到库。这种必要的行为最多是非常罕见的。实现这一点的最简单方法是使用如下静态标志变量:

static bool hasRun = false;
public void doSomething {
    if (hasRun) {
        return;
    }
}

您的意思是在整个程序执行过程中只执行一次,还是您会有允许再次显示的重置条件?在这两种情况下,我建议创建一个包装类,将其实例化为一个字段,并为每个要“仅显示一次”的特定行嵌入bool标志。如果已知字符串是固定的(没有改变它的参数),您还可以使用一个中央服务类来保存一组已打印的字符串。问题在于,您不能从多个位置记录相同的字符串


一个常见的通用解决方案是“报警管理器”,尽管我还没有看到用于此的标准化库。但是,在我的行业中,它经常出现,因为工业机械可能会进入持续报警状态,并且您希望记录到报警状态的转换,但不会持续记录您仍处于报警状态。我所使用/看到的解决方案通常会为每种情况创建一个唯一的报警代码,带有“设置”和“清除”的概念,通常需要操作员干预以确认并最终清除报警。

当您可以执行以下操作时,为什么需要一个库:

private bool wasExecuted = false;

public void foo(){
  if (!wasExecuted) {
     Console.Write("hello");
     wasExecuted = true;
  }
}

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

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;
} 

我知道这是老消息。。。但这里有一个功能性的方法来解决这个问题,有些人可能会觉得有用:

    public static Action<T> Once<T>(Action<T> action )
    {
        return (arg) =>
        {
            action?.Invoke(arg);
            action = null;
        };
    }
公共静态动作一次(动作动作)
{
返回值(arg)=>
{
动作?.Invoke(arg);
action=null;
};
}
然后,您可以生成一个只执行一次主要工作的函数:

    var writeNumberToConsole = Once<int>( Console.WriteLine );
    writeNumberToConsole(1); // "1"
    writeNumberToConsole(2); -> //nothing
    writeNumberToConsole(3); -> //nothing
var writeNumberToConsole=one次(Console.WriteLine);
writeNumberToConsole(1);//"1"
WriteEnumbertoConsole(2);->//没有什么
writeNumberToConsole(3);->//没有什么

通常,诀窍是一开始就不要调用它。你想解决什么问题?这将在什么上下文中使用?
foo()
是事件侦听器吗?这样做会违反其他使用该功能的人的期望为什么如此热衷于使用库?对于使用“基于标志”的解决方案很容易解决的问题来说,似乎有些过分。该方法可以设置一个静态变量,表明它已经被调用。仅供参考,当调用两次时与调用一次时具有相同效果的方法称为“幂等”方法。()通常您要做的是设置一个标志,指示该方法是否已被调用。是的,但他明确要求不要使用标志。@Ernesto:Yeap,但他明确要求一个不存在的库。@Ernesto:他说的是“标志属性”。。。我没有使用任何属性。@FreeAsInBeer,这绝对正确@哈布詹,是的,但我不知道他是否真的有什么意思。除了关于他想要什么的问题过于明确之外,这个答案是解决这个问题的一个完全正确的方法;有一些日志记录功能是很常见的,但是如果条件再次出现,想要禁止重复记录(例如,在轮询循环中检测到连接丢失;您不想记录每次重新连接尝试)。但是,这比只记录一次要复杂一些,当你成功连接后,你需要一种方法来“重置”并允许再次记录。@Dan:我可以看到你的来历,但同时,如果我正在使用这些日志查找bug,我希望得到我能得到的每一点信息。当然,这是真的,但我遇到了一些非常糟糕的边界情况,反复记录了一个持久性条件。在一个案例中,应用程序实际上记录了失败的相机图像并填满了驱动器,导致系统硬崩溃。这是在任何类型的“自动重试”场景中都可能发生的一般问题。即使在不太严重的情况下,它也会使日志更难读取。例如,静态变量的问题是,如果这是一个web应用程序,并且该方法在不同的页面中使用,则只有一个页面会执行代码。+1删除了我的答案,因为这一个提供了示例。这相当于jquery示例。“这样,只有第一次单击按钮才会产生控制台写入。”-这并不完全正确。如果他有多线程代码或以任意数量的特殊方式调用的代码,并且在移除处理程序之前可能会导致1次以上的调用。在方法声明之前添加
[MethodImpl(methodimpoptions.Synchronized)]
将是解决此问题的一种方法!我认为这个想法是foo()中的日志记录只被调用一次,但这仍然是一个聪明的解决方案。它隐式地创建必要的上下文作为包装器方法的一部分,并在闭包中捕获它,这是封装它的好方法。不过,我猜这还不足以解决OP需要解决的真正问题,因为在OP的整个生命周期中,您只想登录一次的问题很少
    var writeNumberToConsole = Once<int>( Console.WriteLine );
    writeNumberToConsole(1); // "1"
    writeNumberToConsole(2); -> //nothing
    writeNumberToConsole(3); -> //nothing