开发者

Detecting if a class/type is defined prior to compiling

开发者 https://www.devze.com 2023-04-10 12:38 出处:网络
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\".

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开发者_Python百科 (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.


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); 


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 :)


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).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号