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

发布于 2024-12-07 20:06:02 字数 964 浏览 0 评论 0原文

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

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

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

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

例如,我知道这不起作用,因为它仅测试是否使用 #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# 新手,因此使用反射的示例(如果可能的话)会很棒。

This is similar to a few other threads i have found, but I haven't found the answer I need yet. I would appreciate a direct answer, even if it is "no, you can't do that".

Is there a way to use one block of code if a class/type exists and another if it doesn't. The result would be the same as using preprocessor directives but without the need to #define and manually comment or un-comment something in a file.

This may be a special use-case. I'm not sure. I'm working in an environment where sets of files can be installed, or not, before anything is compiled. So someone could buy a plugin which gets "installed" (files added to the project) which makes classes/types available for use (like extending an API). I need to provide a workaround if someone doesn't have one of our other plugin packages. I hope that makes sense.

It just wouldn't be user-friendly to ask someone to open up one of our files, if they have another plug-in, to un-comment a preprocessor directive, unless we have to.

e.g. I know this doesn't work because it only tests boolean if #define is used, but it illustrates what I am trying to do...

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

EDIT: I added this as a C# feature suggestion. Please vote here:
http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2297494-add-type-testing-as-preprocessor-directive

I don't see how reflection would be able to do this, but I am new to C#, so examples using relection, if it is possible, would be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

温柔嚣张 2024-12-14 20:06:02

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

C# - 正确的加载程序集、查找类和调用 Run() 方法的方式

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

if (type != null)
    //Do Something

编辑以显示激活器调用

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

var      obj      = Activator.CreateInstance(type); 

Instead of using pre-compiler statements (which I don't know if they would work anyway if the client didn't have to recompile after installing your plug-in), I would suggest querying the assembly and trying to instantiate an instance of the class by string as seen here:

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

Editing to show Activator call

if type is not null then use this to create an instance of the type you want.

var      obj      = Activator.CreateInstance(type); 
煞人兵器 2024-12-14 20:06:02

您可以为您的评估提供的代码支持但不提供的类型/服务定义接口。然后您可以使用 MEF 等插件框架,它内置于 .Net Framework (v4.0) 中。

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

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

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

替代方案想法

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

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

如果您的代码值得分发,您将无法阻止分发。盗版行为是无法预防的。

我最近使用的大多数许可代码都具有全功能但定时的试用版和电话回家功能。他们安装了所有代码,但如果没有获得许可,则简单地禁用其中的部分代码。如果人们无法试用您的高级功能,则很难知道他们是否愿意付费:)

You could define interfaces for your types/services that your evaluation-provided code supports, but doesn't provide. Then you could use a plugin framework like MEF, which is built into the .Net Framework (v4.0).

MEF will do the reflection and assembly enumeration for you. You just have to define simple extension points in your code.

Here is some basic documentation for MEF. It might be specific to the Codeplex version of the code (not sure) but it shouldn't be too old, and should give you a good idea of how it works:

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

Alternative ideas

You might want to solve this with licensing rather than distribution.

You're going to have to solve the licensing problem anyhow, so you can collect money from users, and so you can sue people who grievously violate your copyright.

If your code is worth distributing, you won't be able to prevent distribution. Piracy is not preventable.

And most licensed code I've used recently have full-featured but timed trials, and phone home. They install all the code, but simply disable parts of it if they aren't licensed. It is hard for someone to know if they want to pay for your advanced features if they can't try them out :)

眼眸印温柔 2024-12-14 20:06:02

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

Do you really care what is present at compile-time, or at run-time? You might be able to use a Factory pattern to encapsulate the logic for which class to instantiate assuming that polymorphism is possible (they both share an interface or base class).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文