代码之家  ›  专栏  ›  技术社区  ›  Even Mien

重构调用具有不同参数签名的delgate的方法

  •  1
  • Even Mien  · 技术社区  · 15 年前

    我发现委托不能接受重载的方法签名。如何再添加一级间接寻址?:)

    public static void ProcessFolder(
        ProcessFolderDelegate processFolderDelegate
    )
    {
        using (var esb = ExchangeService.GetExchangeServiceBinding())
        {
            var contactFolder = FolderService.GetPublicFolder(esb,  
                Properties.Settings.Default.ExchangePublicFolderName);
            processFolderDelegate(esb, contactFolder);
        }
    }
    
    public static void ProcessContact(  
        ProcessContactDelegate processContactDelegate,  
        Contact contact  //extra param
    )
    {
        using (var esb = ExchangeService.GetExchangeServiceBinding())
        {
            var contactFolder = FolderService.GetPublicFolder(esb,  
                Properties.Settings.Default.ExchangePublicFolderName);
            processContactDelegate(esb, contactFolder, contact); //extra param
        }
    }
    
    4 回复  |  直到 5 年前
        1
  •  3
  •   Jacob Seleznev    15 年前
        public delegate void Action(TYPE_OF_ESB esb, TYPE_OF_CONTACT_FOLDER contact folder);
        private static void Process(Action action)
        {
            using (var esb = ExchangeService.GetExchangeServiceBinding())
            {
                var contactFolder = FolderService.GetPublicFolder(esb, Properties.Settings.Default.ExchangePublicFolderName);
                action(esb, contactfolder);
            }
        }
    
    Process((esb, contactfolder)=>processFolderDelegate(esb, contactFolder));
    Process((esb, contactfolder)=>processContactDelegate(esb, contactFolder, contact));
    
        2
  •  1
  •   LorenVS    15 年前

    不,你发布的代码实际上是应用这种模式的一种非常简洁的方法。除非有某种方法抽象被调用的方法的类型,或者删除所有类型安全性(我不建议这样做),否则您不会找到更简洁的方法

        3
  •  1
  •   LukeH    15 年前
    public static void ProcessFolder(ProcessFolderDelegate del)
    {
        Process((b, f) => del(b, f));
    }
    
    public static void ProcessContact(ProcessContactDelegate del, Contact contact)
    {
        Process((b, f) => del(b, f, contact));
    }
    
    private static void Process(
        Action<ExchangeServiceBinding, ContactsFolderType> action)
    {
        // i've guessed that esb is of type ExchangeServiceBinding
        // and that contactFolder is of type ContactsFolderType
        // if that's not the case then change the type parameters
        // of the Action delegate in the method signature above
    
        using (var esb = ExchangeService.GetExchangeServiceBinding())
        {
            var contactFolder = FolderService.GetPublicFolder(
                esb, Properties.Settings.Default.ExchangePublicFolderName);
            action(esb, contactFolder);
        }
    }
    
        4
  •  0
  •   Charlie Gevious    15 年前

    您可以使用匿名方法或lambda,如下所示:

    delegate void ProcessDelegate<T>(T param);
    .
    .
    public static void Process<T>(ProcessDelegate<T> processDelegate)
    {
        using (var esb = ExchangeService.GetExchangeServiceBinding())
        {
            var contactFolder = FolderService.GetPublicFolder(esb,  
                Properties.Settings.Default.ExchangePublicFolderName);
            processDelegate(contactFolder);
        }
    }
    

    Process(contactFolder => MyMethod(esb, contactFolder));
    Process(contactFolder => MyMethod(esb, contactFolder, contact));
    

    其中MyMethod是您正在调用的实际方法,因此您将其包含在lambda表达式中,而不是委托中。你觉得那样行吗?