【问题标题】:Ideas for C# template functionC#模板函数的想法
【发布时间】:2021-05-26 18:15:52
【问题描述】:

所以我在 C# 中重构了一个库,它基本上是一些 DLL 的包装器。包装器中有很多函数都共享相同的复制粘贴样板代码。下面是一个示例,它是 C#,其中 arguments 是例如伪代码。 int arg1, bool arg2 等。

public ReturnType foo(arguments)
    {
        if (!isOpen)
        {
           return ReturnType.RESULT_NOT_OPEN;
        }
        if (!Monitor.TryEnter(mutex, mutexTimeout))
        {
          return ReturnType.RESULT_LOCK_TIMEOUT;
           
        }
        
        ReturnType result;
        try { result = SomeFunctionFromDll(handle, arguments); }
        finally { Monitor.Exit(mutex); }
       
        return result;
    }

DLL 函数具有不同类型的参数,但具有与 C# 包装器相同的签名,除了句柄参数。摆脱所有这些样板文件真是太好了。梦境会是这样的

private ReturnType AllCommonBoilerPlate(arguments, dll_function_reference)
{
 // Do mutex, error check etc  
    dll_function_reference(handle, arguments); 
}

public ReturnType foo(arguments)  
   return AllCommonBoilerPlate(arguments, SomeFunctionFromDll);

这个概念在 C# 中可行吗?我尝试过使用委托函数,但找不到解决方案。

我发现我可以将所有初始检查(如 isOpen)并尝试在单独的函数中获取互斥锁,但这并没有太大帮助。另外,这会使互斥体有点模糊。

【问题讨论】:

    标签: c# templates


    【解决方案1】:

    这个概念是完全可行的。希望这有助于给你一个想法:

    private T AllCommonBoilerPlate<T>(Func<T> dll_function_reference, object handle, object arguments)
        {
            if (!isOpen)
            {
                return ReturnType.RESULT_NOT_OPEN;
            }
            if (!Monitor.TryEnter(mutex, mutexTimeout))
            {
                return ReturnType.RESULT_LOCK_TIMEOUT;
    
            }
    
            T result;
            try { result = dll_function_reference(handle, arguments); }
            finally { Monitor.Exit(mutex); }
    
            return result;
        }
    
        public ReturnType foo(object arguments)
        {
            return AllCommonBoilerPlate<ReturnType>(() =>
                {
                    return SomeFunctionFromDll(handle, arguments);
                },
                handle,
                arguments);
        }
    

    【讨论】:

    • 谢谢,这对我来说是一个开始。我看到 AllCommonBoilerPlate 必须是一个通用函数,并且我们必须将 DLL 函数包装在 lambda 中。但是,“参数”不是单个参数,而是具有不同数据类型的多个参数。例如 DllFunctionA(handle, int, ushort), DllFunctionB(handle, uint, int) 等。这会导致转换错误,例如无法从 uint 转换为 ushort。我认为编译器应该能够以某种方式推断出正确的强制转换,因为它只是整数,但我不知道如何。
    • 哦,等等,现在我可以将类型作为模板参数添加为 AllCommonBoilerPlate。好的,这行得通!
    猜你喜欢
    • 2015-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    相关资源
    最近更新 更多