在 .NET 中的编译时检查引用/类型是不是存在

Posted

技术标签:

【中文标题】在 .NET 中的编译时检查引用/类型是不是存在【英文标题】:Checking for the existence a reference/type at compile time in .NET在 .NET 中的编译时检查引用/类型是否存在 【发布时间】:2009-06-04 22:48:16 【问题描述】:

我最近发现需要在编译时检查是否:a)某个程序集引用存在并且可以成功解析,或者b)某个类(其完全限定名已知)被定义。这两种情况对我来说是等价的,所以能够检查其中一种就足够了。有没有办法在.NET/C# 中做到这一点?预处理器指令最初让我觉得可能会有所帮助,但它似乎没有必要的功能。

当然,在运行时检查类型是否存在可以很容易地完成,但不幸的是,在这种情况下这并不能解决我的特定问题。 (我需要能够忽略缺少某个引用的事实,从而回退到代码中的另一种方法。)

【问题讨论】:

【参考方案1】:

您是否有理由不能添加引用,然后对程序集中的类型使用 typeof 表达式来验证它是否可用?

var x = typeof(SomeTypeInSomeAssembly);

如果包含 SomeTypeInSomeAssembly 的程序集未被引用且可用,则无法编译。

【讨论】:

是的。不幸的是,它必须在编译时,否则编译器将尝试编译那个时间并看到它丢失了。当然,我可以用相同的结构/签名定义我自己的类型,但这对我来说似乎很 hack。【参考方案2】:

听起来您希望编译器忽略一个代码分支,这实际上只能通过将其隐藏在#if 块后面来实现。定义编译器常量并使用#if 是否适合您的目的?

#if MyConstant
.... code here that uses the type ....
#else
.... workaround code ....
#endif

另一种选择是在编译时完全不依赖其他类,并使用反射或 .NET 4.0 动态关键字来使用它。如果在 .NET 3.5 或更早版本的性能关键场景中重复调用它,您可以使用 DynamicMethod 在首次使用时构建代码,而不是每次都使用反射。

【讨论】:

这可能更接近我的需要。我自己正在考虑使用 #if 指令和一个预构建脚本,该脚本定义一个常量当且仅当某个引用可以被解析。【参考方案3】:

我似乎在这里找到了解决方案,尽管并不完全符合我最初的希望。

我的解决方案:

我最终做的是创建一个新的构建配置,然后定义一个预编译器常量,我在代码中使用它来确定是使用引用还是回退到替代(保证工作)方法。它不是全自动的,但它相对简单并且看起来相当优雅 - 足以满足我的目的。

替代方案:

如果您想完全自动化,可以使用运行批处理脚本/小程序的预构建命令来检查机器上给定引用的可用性,然后更新包含预编译器常量的文件。然而,我认为这付出了更多的努力,但如果我有多个需要解决的独立参考资料可能会更有用(检查可用性)。

【讨论】:

以上是关于在 .NET 中的编译时检查引用/类型是不是存在的主要内容,如果未能解决你的问题,请参考以下文章

如何在编译时检查是不是存在可以使用特定参数集调用的函数?

静态类型&动态类型

命名空间“系统”中不存在类型或命名空间名称“事务”(您是不是缺少程序集引用?) - C# ASP.NET

为啥在编译时不检查 lambda 返回类型?

ADO.NET DataRow - 检查列是不是存在

C# ASP.NET ASP.NET#命名空间"System.Data"中不存在类型或命名空间名称"Linq"(是否缺少程序集引用?)