我有一个导入外部C ++函数的低级类,例如:
public static class LowLevel
{
[DllImport("DLLName.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int DoStuff([MarshalAs(UnmanagedType.LPStr)] string parameter);
[DllImport("DLLName.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int DoStuff2(int parameter);
...
}
现在,它有很多方法,所有方法都返回错误代码。我想将这些错误代码封装并转换为异常,即:。
public static void DoStuff(string parameter)
{
int error = LowLevel.DoStuff(parameter);
if (error != 0)
throw new MyException(error);
}
有没有办法在没有大量复制粘贴的情况下为很多方法执行此操作?它是一般的好主意还是有更好的方法?在最终显示错误消息等之前,我试图避免必须通过所有受保护的公共,低级到中级到高级抽象类来传递错误代码。
答案 0 :(得分:3)
对于每个实例,您应该问自己的一件事是非零返回值是否实际上等同于异常或可能是预期结果。并非每个具有不同结果的方法都使用这些方法来传达异常情况,如果将这些方法映射到异常中,流控制就会变得......很奇怪。
你的包装看起来很好(我猜想缺少文档)。我可能做的一件事是根据失败代码的含义使用合理的例外情况,例如:抛出FileNotFoundException
而不是MyException(2)
。然而,这几乎排除了任何自动化方法。
至于自动执行此操作,ReSharper允许您根据模式搜索定义快速修复。这有助于至少自动生成一些样板。
另一个选择是Roslyn,Microsoft的开源C#编译器框架。 Visual Studio 2015允许您使用Roslyn的API编写快速修复程序(如果您需要在IDE中集成某些内容(类似于ReSharper提供的内容)。但是你也可以使用这些库来编写一个生成适当粘合代码的小工具。
代码生成的其他选项是T4 templates,至少Visual Studio知道如何在必要时自动重新生成(尽管在构建文件中不会这样做)。我过去也使用PowerShell生成源代码。在一种情况下,通过查看已编译的程序集并基于某个名称空间中的类型和方法生成代码(通过反射枚举),这也可以与您的LowLevel
类一起使用。
但是,自动生成的代码有点棘手。如果您需要对生成的代码进行更改,那么您的选项会更少,或者您需要在源代码管理系统中创造性地使用部分类或分支和合并,以避免使用重新生成的代码破坏手动编写的代码。
我的建议是将生成的代码与文件级别的手写代码完全分开。否则只会造成不必要的麻烦。当然,所有这些都假定您可以更频繁地运行代码生成过程。