替换c# DLL中的#ifdefs
Replace #ifdefs in C# DLL
我有一个c++ DLL,其中有#定义使用如下(这些定义是根据构建配置自动定义的,例如Debug, Release等)
#if defined(CONSTANT)
..
// Some code
#else
// Some other code
我需要c# dll中相同的功能。如果我在c# dll中定义一些全局常量并使用它们,是否可以而不是定义?例如
if(Globals.SomeConstant == SOMEVALUE)
// Do this
else
// Do smth else
然后,当我想运送DLL时,我将提前(可能作为声明期间的默认值)将SOMEVALUE
分配给Globals.SomeConstant
-这会这样工作吗?(取决于我需要的配置)。
我看到了一些类似的问题,但它们不是关于dll的。
您可以像在c++
中那样使用它可以在源代码中定义/取消定义它们,也可以作为条件编译符号。在visual studio中,可以使用解决方案资源管理器-属性-构建-条件编译符号
然而,现在人们倾向于使用配置文件来保存这些常量。这样,您就不必重新编译源代码或重新发布它来改变行为。
最简单的方法是通过visual studio 解决方案资源管理器-属性-设置您可以为大多数类型添加设置。布尔值最接近#define。使用int类型可以提供两种以上的可能性。如果您希望能够为TimeSpan或使用#define的URI使用多个值,请查看困难。
使用设置的好处是生成了一个类,以便您轻松访问设置。
另一种方法是使用System.Configuration.ConfigurationManager类直接读取配置文件。这使您可以更自由地选择配置的格式。缺点是您必须自己将读取的值转换为适当的类型,包括在无法读取值时处理错误。
总结:配置文件法的优点:
- 不需要更改源文件 无需重新编译
- 不需要重新安装
- 只修改那些需要修改的机器上的配置文件
- 改进型安全
我之前的回答引发了更多的问题。因此,我想举个例子会有帮助。
假设我有一个名为MyDll的DLL。它有一个配置设置,在以前是用#define定义的。
我的c语法有点生疏,但它看起来像:
#define UseAlternateGreeting
public class MyClass
{
public string GetGreeting()
{
#if defined UseAlternateGreeting
return "Hello World!";
#else
return "Here I am!";
#endif
}
}
现在假设我们有几个程序使用这个DLL。程序!希望使用默认设置。然而,Program2希望使用替代设置。没有办法解决这个问题。
此外,如果我们想改变设置的值,我们必须重新编译并重新分发所有内容给每个人。
如果我们可以用记事本编辑文件来更改字符串,这不是更容易吗?
幸运的是,微软也看到了这样做的好处。在过去的10多年里,我们有了配置文件的想法。程序集有一个配置文件,其名称为应用程序,扩展名为config。知道配置项含义的人可以使用任何文本编辑器轻松编辑此文件。如果我们用配置文件中的一个项替换#define,那么问候语可以被更改为替代问候语,而不必重新编译和重新分发整个程序。
幸运的是Visual Studio在创建配置文件时帮助了我们很多。
准备- 让Visual Studio在新的解决方案中创建一个控制台应用程序:将程序命名为ConfigExample
- 添加一个新的库到这个应用程序,命名为MyDll 查看MyDll的属性
添加设置。
- 名称:MySetting,
- 类型:字符串,
- 范围:应用程序中,
- 值:Hello World!(不带引号)
在项目MyDll中创建一个类MyClass
公共类MyClass{公共字符串GetText(){返回Properties.Settings.Default.MySetting;}}
进入项目ConfigExample
- 项目添加对MyDll的引用(通过选项卡页面解决方案)
使用main代码:
使用MyDll;静态void Main(string[] args){var obj = new MyClass();var txt = obj.GetText();Console.WriteLine (txt);}
编译并运行,您将看到显示正确的文本。如果你进入程序的debug/bin目录,你会发现一个文本文件ConfigExample.config。在文本编辑器中打开它,你会看到…跟你好世界无关!
这意味着你的程序对特殊设置不感兴趣,可以使用MyDll构建时的默认设置。
但是,如果你想使用一个特殊的设置,
- 在visual Studio中,转到项目MyDll
- 打开文件app.config
- a.o。你会发现下面的
(为了防止编辑器干扰格式,我在每行后面加了一个撇号)
'</configSections>
'<applicationSettings>
'<MyDll.Properties.Settings>
'<setting name="MySetting" serializeAs="String">
'<value>Hello World!</value>
'</setting>
'</MyDll.Properties.Settings>
'</applicationSettings>
- 复制粘贴本部分到ConfigExample。配置
- 对于所有已经发布的程序,在可执行文件所在的文件夹中执行此操作(在您的情况下:debug/bin)
- 对于将来要构建的所有ConfigExample程序,在visual studio中ConfigExample项目的App.Config中执行此操作。
结果如下:
'<?xml version="1.0" encoding="utf-8" ?>
'<configuration>
' <configSections>
' <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="MyDll.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
' </sectionGroup>
' </configSections>
' <applicationSettings>
' <MyDll.Properties.Settings>
' <setting name="MySetting" serializeAs="String">
' <value>Hello World!</value>
' </setting>
' </MyDll.Properties.Settings>
' </applicationSettings>
'
' <startup>
' <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
' </startup>
'</configuration>
现在我们要做的就是把Hello World改成另一种问候语
' <MyDll.Properties.Settings>
' <setting name="MySetting" serializeAs="String">
' <value>Here I am!</value>
' </setting>
' </MyDll.Properties.Settings>
运行程序而不构建它,您将看到使用了新值。
优势:Type.IsAssignableFrom(typeof(string))Visual Studio已经支持很多类型,包括TimeSpan和DateTime。-您不必重新编译源代码来更改值-几个可执行文件可以使用他们自己的配置设置:一个程序可以使用原始的问候,另一个可以使用备用的-如果你的程序没有在配置文件中提供一个值,则使用默认值。-您不需要自己阅读配置。-它是类型安全的:如果你说它是一个TimeSpan,那么你必须做一些严肃的输入来混淆它,例如一个整数。
关于配置还有很多要说的,你甚至可以为每个用户配置。但这远远超出了你关于普通c#替代方案的问题。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- .cpp和.h文件中的模板专用化声明
- 反向给定链表中的K节点
- 正在查找文档以获得PS4平台的C++中的设备信息
- enum是C++中的宏变量还是整数变量
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 将字符串存储在c++中的稳定内存中
- 文本文件中的单词链表
- 递归函数计算序列中的平方和(并输出过程)
- 如何从C++中的依赖类型中获得它所依赖的类型
- C++中的"inline"关键字
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 用C++中的一个变量定义一个常量
- vector.resize()中的分配错误
- 使用指针从C++中的数组中获取最大值
- arr[-1]在c++中的奇怪行为
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 将值指定给向量(2D)的向量中的某个位置
- 替换c# DLL中的#ifdefs