在C#3.5中,如何将对象上的哪个方法作为参数传递

Dav*_*ing 5 c# refactoring delegates .net-3.5

我在C#3.5中有两个相同的bar一个函数调用方法,在下面的代码片段中,请参阅clientController.GetClientUsername vs clientController.GetClientGraphicalUsername

    private static bool TryGetLogonUserIdByUsername(IGetClientUsername clientController, string sClientId, out int? logonUserId)
    {
        string username;
        if (clientController.GetClientUsername(sClientId, out username))
        {
           // ... snip common code ...
        }

        return false;
    }

    private static bool TryGetLogonUserIdByGraphicalUsername(IGetClientUsername clientController, string sClientId, out int? logonUserId)
    {
        string username;
        if (clientController.GetClientGraphicalUsername(sClientId, out username))
        {
           // ... snip common code ...
        }

        return false;
    }
Run Code Online (Sandbox Code Playgroud)

有没有办法(委托,lamda的?)我可以传递给我想调用的clientController上的哪个方法?

谢谢!

Meh*_*ari 9

虽然您可以将委托作为参数传递,但我建议使用不同的路径.封装if涉及另一个函数中的公共代码的语句的主体,并在两个函数中调用该代码.

Visual Studio ->在上下文菜单中具有"重构提取方法"功能.您只需填写其中一个实体,选择实体并使用该功能自动提取其中的方法.

  • @Mark:我同意这种风格在函数式语言中有意义,但C#不是纯粹的函数式语言.虽然LINQ和lambdas真的很棒并且为语言添加了功能意义,但它*并不能取代C#的命令性方面*.当命令式风格更适合时,我认为没有理由牺牲语言的简洁性. (2认同)

Jos*_*h G 7

当然.只需像这样定义一个委托:

public delegate bool GetUsername(string clientID, out string username);
Run Code Online (Sandbox Code Playgroud)

然后将其传递给您的函数并调用它:

private static bool TryGetLogonUserId(IGetClientUsername clientController, string sClientId, out int? logonUserId, GetUsername func)
{
    string username;
    if (func.Invoke(sClientId, out username))
    {
       // ... snip common code ...
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

要使用委托调用该函数,您将执行以下操作:

TryGetLogonUserId(/* first params... */, clientController.GetClientUsername);
Run Code Online (Sandbox Code Playgroud)

  • 你在说什么是糟糕的风格?通过代表?我刚回答这个问题.在委托上调用".Invoke()"?我更喜欢这种表示法,因为它清楚地表明您正在使用委托. (2认同)
  • 我和Josh G在一起,这似乎是一个非常优雅的问题解决方案,如果你仔细地命名"func",那就明白发生了什么 (2认同)