.net 应该“;行动”;委托是否可以重构为新方法?

.net 应该“;行动”;委托是否可以重构为新方法?,.net,generics,refactoring,.net,Generics,Refactoring,我有以下方法 private void SetProcessDocumentStatus(string status) { var setStatusWith = new Action<string>( statusValue => processDocumentStatusLabel.Text = statusValue); if (processDocumentStatusLabel.InvokeReq

我有以下方法

    private void SetProcessDocumentStatus(string status)
    {
        var setStatusWith = new Action<string>(
            statusValue => processDocumentStatusLabel.Text = statusValue);
        if (processDocumentStatusLabel.InvokeRequired)
            processDocumentStatusLabel.Invoke(
                (MethodInvoker)(() => setStatusWith(status)));
        else
            setStatusWith(status);
    }

我想知道在代码中是否应该少用“Action”委托。

我对您所做的似乎非常清楚。将lambda移动到一个单独的函数会增加代码行,但不清楚

我可能会将第一行写为:

  Action<string> setStatusWith = 
    statusValue => processDocumentStatusLabel.Text = statusValue;
Action setStatusWith=
statusValue=>processDocumentStatusLabel.Text=statusValue;

但我不知道哪种方式通常更受欢迎

我对你所说的似乎非常清楚。将lambda移动到一个单独的函数会增加代码行,但不清楚

我可能会将第一行写为:

  Action<string> setStatusWith = 
    statusValue => processDocumentStatusLabel.Text = statusValue;
Action setStatusWith=
statusValue=>processDocumentStatusLabel.Text=statusValue;

但我不知道哪种方式通常更受欢迎

使用动作委托本身没有什么问题。我认为这里应该有两个单独的方法的唯一原因是,如果您觉得需要绕过检查,以查看invokererequired属性是否为true,并且必须封送调用。然而,我认为没有明确的理由这样做


就个人而言,我认为检查invokererequired然后封送对自身的调用的代码是个坏主意。我更喜欢调用者必须知道他们所处的环境(是UI线程还是非UI线程),然后决定是否封送调用。

使用动作委托本身没有什么问题。我认为这里应该有两个单独的方法的唯一原因是,如果您觉得需要绕过检查,以查看invokererequired属性是否为true,并且必须封送调用。然而,我认为没有明确的理由这样做


就个人而言,我认为检查invokererequired然后封送对自身的调用的代码是个坏主意。我更喜欢调用者必须知道他们所处的环境(是UI线程还是非UI线程),然后决定是否封送调用。

如果有的话,我会将逻辑包装起来,在函数中执行调用,因为这是将被多次使用的逻辑(基本上所有可以设置为异步的函数)

private void SetProcessDocumentStatus(字符串状态)
{
跑步控制(
processDocumentStatusLabel,
statusValue=>processDocumentStatusLabel.Text=statusValue,
地位);
}
私有无效运行控制(控制、操作、T参数)
{
if(control.invokererequired)
调用(操作,参数);
其他的
行动(参数);
}

如果有的话,我会将逻辑包装起来,在函数中执行调用,因为这是将要多次使用的逻辑(基本上所有可以设置为异步的函数)

private void SetProcessDocumentStatus(字符串状态)
{
跑步控制(
processDocumentStatusLabel,
statusValue=>processDocumentStatusLabel.Text=statusValue,
地位);
}
私有无效运行控制(控制、操作、T参数)
{
if(control.invokererequired)
调用(操作,参数);
其他的
行动(参数);
}

在本例中,您让操作接受一个参数:
操作
,但您只传递相同的参数,即
状态
。因此它不需要接受参数-也许您不知道lambda捕获变量的能力

private void SetProcessDocumentStatus(string status)
{
    Action setStatusWith = () => processDocumentStatusLabel.Text = status;

    if (processDocumentStatusLabel.InvokeRequired)
        processDocumentStatusLabel.Invoke(() => setStatusWith());
    else
        setStatusWith();
}
或者调整艾伦·杰克逊的优秀答案:

private void SetProcessDocumentStatus(string status)
{
    processDocumentStatusLabel.Run(ctrl => ctrl.Text = status);
}

public static class ControlExtensions
{
    public static void Run<T>(this TControl control, Action<TControl> action)
        where TControl : Control
    {
        if (control.InvokeRequired)
            control.Invoke(() => action(control));
        else
            action(control);
    }
}
private void SetProcessDocumentStatus(字符串状态)
{
processDocumentStatusLabel.Run(ctrl=>ctrl.Text=status);
}
公共静态类控件扩展
{
公共静态无效运行(此TControl控件、操作)
其中TControl:Control
{
if(control.invokererequired)
control.Invoke(()=>action(control));
其他的
行动(控制);
}
}

在这里,我让操作将控件作为一个参数。我还将helper方法作为一个扩展,这似乎是合理的。

在本例中,您让操作接受一个参数:
Action
,但之后您只传递同一个参数,
status
。因此它不需要接受参数-ma你是否不知道lambda捕获变量的能力

private void SetProcessDocumentStatus(string status)
{
    Action setStatusWith = () => processDocumentStatusLabel.Text = status;

    if (processDocumentStatusLabel.InvokeRequired)
        processDocumentStatusLabel.Invoke(() => setStatusWith());
    else
        setStatusWith();
}
或者调整艾伦·杰克逊的优秀答案:

private void SetProcessDocumentStatus(string status)
{
    processDocumentStatusLabel.Run(ctrl => ctrl.Text = status);
}

public static class ControlExtensions
{
    public static void Run<T>(this TControl control, Action<TControl> action)
        where TControl : Control
    {
        if (control.InvokeRequired)
            control.Invoke(() => action(control));
        else
            action(control);
    }
}
private void SetProcessDocumentStatus(字符串状态)
{
processDocumentStatusLabel.Run(ctrl=>ctrl.Text=status);
}
公共静态类控件扩展
{
公共静态无效运行(此TControl控件、操作)
其中TControl:Control
{
if(control.invokererequired)
control.Invoke(()=>action(control));
其他的
行动(控制);
}
}

在这里,我让操作将控件作为一个参数。我还将helper方法作为一个扩展,这似乎是合理的。

如果重新调整示例,您将发现不需要向操作传递参数。lambda可以直接捕获状态参数。我在“RunOnControl”中看到了该模式方法。现在是我将其封装到方法中的时候了。谢谢。如果重新调整示例,您将发现不需要向操作传递参数。lambda可以直接捕获状态参数。我在“RunOnControl”中看到了模式方法。现在是我将其封装成方法的时候了。谢谢。@EarWicker我刚刚进入.net 3.5世界,但我不知道这些功能。谢谢你指出。EarWicker,这正是我希望函数看起来的样子。更干净。@EarWicker我刚刚进入.net 3.5世界,但我不知道意识到的