具有多个外观的C#Windows窗体应用程序 - 条件编译是一个很好的解决方案吗?

时间:2014-05-01 00:14:06

标签: c# winforms compilation conditional

我有.NET Windows Forms应用程序,它已经变得如此受欢迎(只是开玩笑),现在我需要再做3个完全这样的,除了图标,一些标题和少数几个标签。

我已经使用以下代码完成了所有工作:

#if CCA
  myLabel.Text = "Version A";
#endif
#if CCB
  myLabel.Text = "Version B";
#endif
...etc...

我为每个条件编译符号(例如CCA,CCB等)设置了Visual Studio项目/解决方案“配置”,并且我的AssemblyInfo中还有一些#if .. #endif块。 cs文件来处理程序集标题等。当我需要构建时,我只需更改配置,更新我的图标(我没想办法让图标成为条件),然后重建。这里的优点是我有一个代码库,如果我需要进行更改,我只需要进行一次。

我对这个解决方案非常满意,但是因为我在几周前看到NLog源代码中使用的条件编译之后我自己就把它们整合在一起了,我想在这里仔细检查一下这个小组的想法:

我正在做一个公认的方法来实现这个目标吗? 有没有更好的办法? 有任何缺点吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

我建议不要使用条件编译来读取文件中的值。

如果不是很多,app.config是存储该信息的好地方。如果您不希望以纯文本显示配置信息,则可以将每个版本的一个配置文件存储为EXE中的资源,并在运行时加载所需的配置文件。您可以使用app.config指示应该使用哪个版本。

无论哪种方式,当应用程序首次加载时,您将读取配置的值并使用这些值初始化相关控件。

这样,只需对app.config文件进行少量更改即可分发一个版本的程序。

答案 1 :(得分:2)

我建议远离条件编译。因为他们创建了“死代码”,意思是代码已经到位但不编译(就像评论一样)。

如果您只是更改程序集标题等,那就完全没问题了,但如果您根据编译参数更改了某个功能,那么您应该考虑更好的方法。

假设你有

private void SomeMethod()
{
    //Some code
    #if CCA
       DoSomething();
    #endif
}
private void DoSomething()
{ }

当您重构代码库并在关闭DoSomething开关时将DoSomethingInteresting更改为CCA时会发生什么?怎么了?你破坏了你的代码。但是它仍然可以编译,在你打开CCA之前你不会意识到这一点。脆弱不是吗?

我建议您将所有业务逻辑,UI等移动到库(dll)中,然后创建一个“BootStapper”项目,该项目是一个可执行文件,它引用该dll并启动应用程序。

创建一个静态类,即ApplicationConfig或类似的类似;从bootstrapper本身设置必要的属性。

public class ApplicationConfig
{
    public static string VersionText { get; set; }
}

然后你可以简单地做

myLabel.Text = ApplicationConfig.VersionText;

你会得到什么好处?

  • 您可以更改装配标题等
  • 您可以更改图标
  • 您删除了脆弱的代码

有什么不利之处

  • 你需要很多bootstrapper项目(没关系)
  • 您将该功能编译为他们不需要的人