替换c# DLL中的#ifdefs

Replace #ifdefs in C# DLL

本文关键字:#ifdefs 中的 DLL 替换      更新时间:2023-10-16

我有一个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#替代方案的问题。