【问题标题】:C# precompiler directive to avoid reflection避免反射的 C# 预编译器指令
【发布时间】:2015-06-15 03:44:39
【问题描述】:

在我的场景中,我有同一个库的某个版本。

例如,假设我的库名称是 lib.dll,并且该库有两个版本。

在这个例子中,每个库只包含一个类(称为 Dummy ),只有一个方法,但每个库中方法的签名会根据版本而变化。

现在我需要开发一个使用以前的 lib.dll 但需要与每个版本兼容的新库。

假设版本为 1.0.0.0 的 lib.dll 支持该方法:

Dummy.Method ( int )

lib.dll 使用 2.0.0.0 版本代替该方法:

Dummy.Method ( string , int )

在我使用 lib.dll 开发的库中,我将能够与两个 lib.dll 版本向后兼容,但无需使用反射来调用具有不同签名的方法。 是否支持这样的预编译器语法:

 #IF lib.dll VERSION IS 1.0.0.0 
      Dummy.Method ( 1 ) ;
 #ENDIF

 #IF lib.dll VERSION IS 2.0.0.0 
      Dummy.Method ( "test" , 1 ) ;
 #ENDIF

这样根据库的引用版本;一个代码分支,或者另一个被使用。

【问题讨论】:

  • 您是否希望编译后的程序集只与旧库之一兼容,而不是两者都兼容?
  • 不,没有编译器指令可以这样处理这个问题。您可以在项目构建选项中添加定义名称,并使用#if lib_1#if lib_2,但根据您引用的程序集版本,它不会是自动的。
  • 如果您想要像示例所示的早期绑定(而不是 Reflection 或 dynamic),那么您已经必须对新库进行两次构建——一个引用 lib_1和一个引用 lib_2 的。到那时,根据您正在编译的版本指定不同的条件编译指令(如 Lasse 建议的那样)应该不是问题。
  • @JoeWhite 我不清楚如何在您的场景中指定指令编译,我想我不仅需要更改我将兼容的 lib.dll,而且还需要更改一些#definition 指令这告诉我当前使用的是哪个 lib.dll 版本,还是我错过了重点?再次感谢您的帮助
  • 项目属性 > 构建选项卡 > 条件编译符号。请参阅 herehere。使用一个条件编译符号(例如lib_1)构建一次,然后使用另一个编译符号再次构建。这是一项相当多的工作,但它也是您要满足的非常不寻常的要求。

标签: c# reflection compatibility preprocessor-directive


【解决方案1】:

Visual Studio 2019 下的 C# 确实可以实现这一点。

它们被称为生成器。

(见https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/)。

这个想法是在编译时创建你的方法。 因此,生成器将检查 lib.dll 版本并生成足够的代码来调用实际方法 - 上面的 Dummy.method()。

【讨论】:

  • @Wolfang 似乎是一项有趣的技术,我会记住的。与此同时,情况发生了很大变化,我再也没有这个问题了。无论如何感谢您的提示。
  • @Skary: "我没有那个问题了" -- 如果问题不再存在并且你没有办法正确评估这个问题的答案,特别是要确定一个答案是否应该被接受,那么最好只是删除问题,以免分散对可以回答和接受的问题的注意力。
  • @PeterDuniho 所以应该在无法评估的那一刻删除多年来保持开放的问题?非常难处理的任务,希望 stackoverflow 能够自动删除(基于未解决问题的超时);同时感谢我会记住的提示。 PS:我还没有删除这个问题,因为我已经把它转发给了我以前的同事。
猜你喜欢
  • 2013-08-22
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
  • 2021-11-22
  • 2011-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多