【问题标题】:Invoke a function in a fixed piece of code / expose an object from wrapper class在一段固定的代码中调用一个函数/从包装类中公开一个对象
【发布时间】:2015-01-23 11:38:33
【问题描述】:

这可能是一个奇怪的问题。 我有一个“代码”,我需要用它“包装”一些函数。 为了更简洁,我正在为字典构建一个包装类,并且我有一些“pre”和“post”操作要做,所有这些都在一个 try-catch-finally 块中,在中间,我想调用一个函数。

我实际上在做的是公开所有字典方法(以符合接口 IDictionary),并且我希望/需要全部实现它们,并且每个方法都应该“插入”到我的“一段代码”中。例如,这是我的ContainsKey(TKey key)

public bool ContainsKey(TKey key)
    {
        bool IsLockTaken = false;

        try
        {
            // Acquire the lock:
            Monitor.TryEnter(SyncRoot, MonitorEnterTimeout, ref IsLockTaken);
            if (!IsLockTaken)
            {
                Log(@"Failed to Enter a monitor.");
                return false;
            }

            /* INVOKE HERE */
            return MyDict.ContainsKey(key); 
        }
        catch (System.Exception ex)
        {
            Log(String.Format("Error: {0}", ex.ToString()));
            return false;
        }
        finally
        {
            if (IsLockTaken)
            {
                Monitor.Exit(SyncRoot);
            }
        } 
    }

所以我真正需要的是每个函数,将调用放在“INVOKE HERE”部分。 有没有一种不错的、正确的方法来做到这一点,没有代码重复? 谢谢

【问题讨论】:

    标签: c# oop dictionary delegates wrapper


    【解决方案1】:

    你可以有一个函数,它本身接受一个函数,并且总是像这样进行预处理和后处理:

    public bool ContainsKey(TKey key)
    {
       bool result = false;
       WrapFunction(() => { result = MyDict.ContainsKey(key); });
    
       return result;
    }
    
    public void Clear()
    {
       WrapFunction(() => MyDict.Clear());
    }
    
    private void WrapFunction(Action<T> action)
    {
        bool IsLockTaken = false;
    
        try
        {
            // Acquire the lock:
            Monitor.TryEnter(SyncRoot, MonitorEnterTimeout, ref IsLockTaken);
            if (!IsLockTaken)
            {
                Log(@"Failed to Enter a monitor.");
                return;
            }
    
            action(); 
        }
        catch (System.Exception ex)
        {
            Log(String.Format("Error: {0}", ex.ToString()));
            return;
        }
        finally
        {
            if (IsLockTaken)
            {
                Monitor.Exit(SyncRoot);
            }
        } 
    }
    

    不过,您必须检查您的错误条件处理。显然,对于一个通用的T,返回false 是不够的。也许你需要一个额外的参数来返回错误。

    我已对其进行了更改,以便您可以处理动作和函数。

    【讨论】:

    • 很好的解决方案,虽然你不能将它重用于 void 方法。知道如何将代码重用于 voids?
    • @MotiAzu 我添加了一些东西来处理动作和函数。
    • 创意!你甚至可以用同样的想法创建一个接受Func&lt;T&gt;WrapFunction
    猜你喜欢
    • 2021-04-24
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 1970-01-01
    • 2022-11-19
    相关资源
    最近更新 更多