在编译之前检测是否定义了类/类型

时间:2011-10-05 02:06:00

标签: c# types c-preprocessor

这与我找到的其他一些主题类似,但我还没有找到我需要的答案。我会很感激直接回答,即使它是“不,你不能那样做”。

如果存在类/类型,是否存在使用一个代码块的方法,如果不存在,则有另一种方法可以使用另一个代码块。结果与使用预处理程序指令相同,但不需要#define并在文件中手动注释或取消注释。

这可能是一个特殊用例。我不确定。在编译任何内容之前,我正在一个可以安装或不安装文件集的环境中工作。所以有人可以购买一个插件,它被“安装”(添加到项目中的文件),这使得类/类型可供使用(如扩展API)。如果有人没有我们的其他插件包,我需要提供一个解决方法。我希望这是有道理的。

如果他们有另一个插件,要求别人打开我们的一个文件,取消对前处理程序指令的注释,除非我们必须这样做,否则用户不会友好。

e.g。我知道这不起作用,因为它只测试布尔值,如果使用了#define,但它说明了我要做的事情......

#if SomeType
    SomeType.DoSomething();
#else
    DefaultWay.DoSomething();

编辑:我将此添加为C#功能建议。请在这里投票: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2297494-add-type-testing-as-preprocessor-directive

我不知道反射是如何做到这一点的,但我不熟悉C#,所以使用relection的例子,如果可能的话,会很棒。

3 个答案:

答案 0 :(得分:4)

我没有使用预编译器语句(我不知道如果客户端在安装插件后不必重新编译它们是否会工作),我建议查询程序集并尝试实例化这里看到的类的字符串实例:

C# - Correct Way to Load Assembly, Find Class and Call Run() Method

Assembly assembly = Assembly.LoadFile(@"C:\dyn.dll"); 
Type     type     = assembly.GetType("TestRunner");  

if (type != null)
    //Do Something

编辑以显示Activator调用

如果type不为null,则使用它来创建所需类型的实例。

var      obj      = Activator.CreateInstance(type); 

答案 1 :(得分:2)

您可以为评估提供的代码支持的类型/服务定义接口,但不提供。然后你可以使用a plugin framework like MEF,它构建在.Net Framework(v4.0)中。

MEF将为您执行反射和汇编枚举。您只需在代码中定义简单的扩展点即可。

以下是MEF的一些基本文档。它可能特定于Codeplex版本的代码(不确定),但它不应该太旧,并且应该让你很好地了解它是如何工作的:

http://mef.codeplex.com/wikipage?title=Guide&referringTitle=Documentation

其他想法

您可能希望通过许可而非分发来解决此问题。

您无论如何都必须解决许可问题,因此您可以从用户那里收钱,这样您就可以起诉那些严重侵犯您版权的人。

如果您的代码值得分发,您将无法阻止分发。盗版是不可避免的。

我最近使用过的大多数许可代码都有功能齐全的定时试用版和电话回家版。他们安装所有代码,但如果没有许可,只需禁用部分代码。如果他们无法尝试,他们很难知道他们是否愿意为您的高级功能付费:)

答案 2 :(得分:0)

您是否真的关心编译时或运行时出现的内容?您可以使用Factory模式来封装实例化类的逻辑,假设可以实现多态(它们共享接口或基类)。