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

C# 在编译之前检测是否定义了类/类型,c#,types,c-preprocessor,C#,Types,C Preprocessor,这与我找到的其他几个线程类似,但我还没有找到我需要的答案。我希望得到一个直接的回答,即使是“不,你不能那样做” 有没有一种方法可以在类/类型存在时使用一个代码块,在不存在时使用另一个代码块。结果与使用预处理器指令相同,但不需要#定义并手动注释或取消注释文件中的某些内容 这可能是一个特殊的用例。我不确定。我在一个环境中工作,在编译任何东西之前,可以安装或不安装文件集。因此,有人可以购买一个“已安装”(添加到项目中的文件)的插件,该插件使类/类型可供使用(比如扩展API)。我需要提供一个解决办法,如

这与我找到的其他几个线程类似,但我还没有找到我需要的答案。我希望得到一个直接的回答,即使是“不,你不能那样做”

有没有一种方法可以在类/类型存在时使用一个代码块,在不存在时使用另一个代码块。结果与使用预处理器指令相同,但不需要#定义并手动注释或取消注释文件中的某些内容

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

如果要求某人打开我们的一个文件(如果他们有另一个插件的话),取消对预处理器指令的注释,这对用户来说是不友好的,除非我们必须这样做

e、 我知道这不起作用,因为它只在使用#define时测试布尔值,但它说明了我正在尝试做什么

#如果某个类型
DoSomething();
#否则
DefaultWay.DoSomething();
EDIT:我将此添加为C#功能建议。请在这里投票:


我不知道反射是如何做到这一点的,但我对C#还不熟悉,所以如果可能的话,使用relection的示例将非常好。

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

编辑以显示激活器呼叫

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

var      obj      = Activator.CreateInstance(type); 

您可以为您的类型/服务定义接口,您的评估提供了代码支持,但没有提供。然后可以使用,它内置在.Net Framework(v4.0)中

MEF将为您执行反射和程序集枚举。您只需要在代码中定义简单的扩展点

下面是一些MEF的基本文档。它可能特定于代码的Codeplex版本(不确定),但不应该太旧,并且应该让您对其工作原理有一个很好的了解:

备选方案

您可能希望通过许可而不是分发来解决这个问题

无论如何,你必须解决授权问题,这样你才能从用户那里筹集资金,这样你才能起诉严重侵犯你版权的人

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


我最近使用的大多数授权代码都有功能齐全但定时的试用版,还可以打电话回家。他们安装了所有的代码,但如果没有获得许可,只需禁用部分代码。如果某人不能试用您的高级功能,他们很难知道是否愿意为这些功能付费:)

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

我不确定MEF在这里如何工作。我们对应用程序没有控制权,只有一段代码可以在自己的代码中使用,所有代码都在应用程序中使用(这是一个游戏引擎,如果重要的话)。。。本例中的发行版没有实际安装。为了简化,您只需将一些文件添加到项目中,就像编写代码一样。如果文件在那里,类型就在那里。我们确实宣布许可,但本质上相当简单。你可以使用它,如果你不重新分发,等等。我们甚至不担心社区中少数不光彩的人。@Rafe:你在你的OP中说“文件”,我认为是指程序集。几乎所有的非开源.Net项目都是作为程序集分发的,所以这里肯定有一个特例。这很好,但这就是为什么我没有说的不仅仅是“使用MEF”:)如果您将插件作为程序集分发(接受的答案只有在您是的情况下才有效),那么您可以使用MEF。您可以分发一个只包含插件接口的程序集,使用这些接口在源文件中创建扩展点,并使用插件实现这些接口。@Rafe:如果MEF提供了足够的好处来保证使用它,则由您决定。无论如何,您都必须在插件和代码之间定义一个契约,而且根据接口编写代码要比根据
对象
编写代码容易得多。这也将提供良好的性能(加载类型后仅进行虚拟函数调用)。其他解决方案包括扩展使用反射调用(每次调用、属性访问等),使用
dynamic
执行相同的操作,或者可能编译动态方法(请参见:)@Rafe:另外,非常感谢您提供的所有信息。我只是不能证明我需要花费所有的时间来学习这些东西来获得一个“很好拥有”的特性,因为我可能再也不需要代码了。我不明白为什么C#没有将此作为预处理器指令。这将使一切变得如此简单。我宁愿制作一个培训视频,让大家发表一个“定义”的评论。如果intellesense能够实时确定某个类型是否存在并提供反馈,那么对于编译器来说这应该不会有问题!希望这些都能帮助下一个家伙。是的,编译时,如果我使用的术语正确的话。例如,它需要与intellisense一起工作。这看起来很有希望。我发现我可以使用GetExecutionGassembly获取当前程序集(未测试,还有其他选项)。问题是,即使我将类型作为变量,智能用户也无法识别
var      obj      = Activator.CreateInstance(type);