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

时间:2009-06-22 11:21:43

标签: c# .net-3.5 delegates refactoring

我在C#3.5中有两个方法,它们是相同的一个函数调用,  在下面的代码段中,请参阅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;
    }

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

谢谢!

5 个答案:

答案 0 :(得分:9)

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

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

答案 1 :(得分:7)

不确定。只需像这样定义一个委托:

public delegate bool GetUsername(string clientID, out string username);

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

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

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

TryGetLogonUserId(/* first params... */, clientController.GetClientUsername);

答案 2 :(得分:1)

函数的类型写为Func< inParam1,inParam2,...,returnParam>。我不确定“out”参数是否在“Func”类型中正确传递,但你应该能够使你的功能像

void TryGetLogon(Func<IGetClientUsername, string, out int?, bool> f) { 
   // ...
   f(x, y, z, a);
}
// ...
TryGetLogon(TryGetLogonUserIdByGraphicalUsername);

答案 3 :(得分:0)

您可以传递MethodInfo,可以静态查找。但是,我同意可能需要重新设计。

private static readonly MethodInfo getRegularLogin = typeof(IGetClientUsername).GetMethod("GetClientUsername");
private static bool TryGetLogonUserIdByUsername(IGetClientUsername clientController, string sClientId, out int? logonUserId)
{

    string username;
    return TryGetLoginReflective(getRegularLogin, clientController, sClientId, out username, out logonUserId);
}

private static readonly MethodInfo getGraphicalLogin = typeof(IGetClientUsername).GetMethod("GetClientGraphicalUsername");
private static bool TryGetLogonUserIdByGraphicalUsername(IGetClientUsername clientController, string sClientId, out int? logonUserId)
{
    string username;
    return TryGetLoginReflective(getGraphicalLogin,  clientController, sClientId, out username, out logonUserId);
}

private static bool TryGetLoginReflective(MethodInfo method, IGetClientUsername clientController, string sClientId, out string username, out int? logonUserId)
{
    object[] args = new object[]{sClientId, null};
    if((bool)method.Invoke(clientController, args))
    {
         // ... snip common code ...
    }
    logonUserId = ...;

    username = (string)args[1];
    return false;
}

答案 4 :(得分:0)

如何简单地传入一个布尔标志?

private static bool TryGetLogonUserIdByUsername(
    IGetClientUsername clientController,
    string sClientId, out int? logonUserId, bool graphical)
{
    string username;
    bool gotClient = false;

    if (graphical)
    {
        gotClient = clientController.GetClientGraphicalUsername(
            sClientId, out username);
    }
    else
    {
        gotClient = clientController.GetClientUsername(
            sClientId, out username);
    }

    if (gotClient)
    {
               // ... snip common code ...
    }

    return false;
}