Preprocessor directives across different files in C#

我与影子孤独终老i 提交于 2019-11-26 21:35:47

问题


I know that I can use preprocessor directives in C# to enable/disable compilation of some part of code.

If I define a directive in the same file, it works fine:

#define LINQ_ENABLED
using System;
using System.Collections.Generic;

#if  LINQ_ENABLED
using System.Linq;      
#endif

Now, I'm used in C++ at putting all this configuration directives inside a single header file, and include it in all files where I need such directives.

If I do the same in C# something doesn't work:

//Config.cs
#define LINQ_ENABLED

//MyClass.cs
#define LINQ_ENABLED
using System;
using System.Collections.Generic;

#if  LINQ_ENABLED
using System.Linq;      
#endif

I also tried the following but seems that I can't define a directive inside a namespace:

//Config.cs
namespace Conf{
#define LINQ_ENABLED
}

//MyClass.cs
#define LINQ_ENABLED
using System;
using System.Collections.Generic;
using Conf;
#if  LINQ_ENABLED
using System.Linq;      
#endif
  1. What am I doing wrong?
  2. What's the right way of using preprocessor across different files in C#?
  3. Is there any better way to do that?

回答1:


In your .csproj there is a section:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DefineConstants>TRACE;DEBUG;LINQ</DefineConstants>
  </PropertyGroup>
</Project>

If you want extra preprocessors you can add them there.

Or via the properties of the project which will add them there automatically for you. In properties under the Build tab.




回答2:


You can do it for the entire project from Project|Properties.

Afaik there is no way to use include files in C# so for groups of files there is no easy solution.




回答3:


Instead of adding conditional compilation to your files, and adding blocks of code which use Linq, and others, which don't. I'd moved all data-access logic (i.e. code which have two implementations - with Linq and without) to separate libraries.

E.g. create interfaces, which your main application will use. And create two implementations of those interfaces - one which use Linq, and another which don't use:

In main project:

public interface IUserRepository
{
    IEnumerable<User> GetUsersByCompanyName(string companyName);
}

In Persistence.Linq.dll :

using System.Linq; 

public class UserRepository : IUserRepository
{
    public IEnumerable<User> GetUsersByCompanyName(string companyName)
    // use Linq here
}

In Persistence.SomethingOther.dll:

public class UserRepository : IUserRepository
{
    public IEnumerable<User> GetUsersByCompanyName(string companyName)
    // do not use Linq here
}

Now you can inject any implementation of IUserRepository into your main application classes.




回答4:


There is no sense of applying #define on usings, as in this way you don't unlink from your project the libraries, that I suppose, you would like to avoid to reference in some condition.

There is no such thing in .NET as conditional assemblies reference (if not done manually, dynamically).

So the main point of use of preprocessor directives is just enable/disable parts of the code inside namespaces.



来源:https://stackoverflow.com/questions/13836501/preprocessor-directives-across-different-files-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!