代码之家  ›  专栏  ›  技术社区  ›  David Laing

在C 3.5中,如何传递将对象作为参数调用的方法

  •  5
  • David Laing  · 技术社区  · 16 年前

    我在C 3.5中有两个方法是相同的bar-one函数调用, 在下面的代码段中,请参见clientcontroller.getclientUsername与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;
        }
    

    有办法吗(代表,拉姆达的?)我可以在clientcontroller上传递我要调用的方法?

    谢谢!

    5 回复  |  直到 16 年前
        1
  •  7
  •   Josh G    16 年前

    当然。像这样定义一个委托:

    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
  •  9
  •   Mehrdad Afshari    16 年前

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

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

        3
  •  1
  •   Mark Rushakoff    16 年前

    函数的类型写为func<inParam1、inParam2、…、returnParam>。我不确定“out”参数是否在“func”类型中正确传递,但是您应该能够使您的函数

    void TryGetLogon(Func<IGetClientUsername, string, out int?, bool> f) { 
       // ...
       f(x, y, z, a);
    }
    // ...
    TryGetLogon(TryGetLogonUserIdByGraphicalUsername);
    
        4
  •  0
  •   Kevin Newman    16 年前

    简单地传入一个布尔标志怎么样?

    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;
    }
    
        5
  •  0
  •   Matthew Flaschen    16 年前

    你可以通过 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;
    }