【问题标题】:Check if reference is present at compile time检查编译时是否存在引用
【发布时间】:2013-11-04 22:40:41
【问题描述】:

是否可以在 C# 编译时检查项目中是否存在引用?

例如;

public void myMethod()
{
    #if REVIT_DLL_2014
       TopographySurface.Create(vertices); // This function only exists in Revit2014.dll
       // So I will get a compiler if another DLL is used 
       // ie, Revit2013.dll, because this method (Create) wont exist
    #else // using Revit2013.dll
       // use alternate method to create a surface
    #endif
}

我要避免的是维护 2 个单独的 C# 项目(即 2013 版和 2014 版),因为它们几乎在所有方面都相同,除了 1 个功能。

我想我最后的手段可能是(但如果上述功能是可能的,那就更好了):

#define USING_REVIT_2014

public void myMethod()
{
    #if USING_REVIT_2014
       TopographySurface.Create(vertices); // This function only exists in Revit2014.dll
       // So I will get a compiler if another DLL is used because this method (Create) wont exist
    #else // using Revit2013.dll
       // use alternate method to create a surface
    #endif
}

【问题讨论】:

  • 我不知道你可以在 C# 中使用 #DEFINE 和 #IF 等:我以为只有 C 或 C++
  • @Joe 是的,你可以使用 defineif 但你不能这样做(这真的很烦人)#if x > y 只有像 #if DEBUG 这样的简单 if 语句
  • 'Create' 是静态方法吗?
  • @AlessandroD'Andria 是的,它是静态的

标签: c# compiler-construction reference


【解决方案1】:

在运行时而不是编译时进行检测。

if (Type.GetType("Full.Name.Space.To.TopographySurface") != null) {
    TopographySurface.Create(vertices);
}
else {
    // use alternate method to create a surface
}

这假定只要定义了TopographySurface,那么Create 就存在。

【讨论】:

  • @JakeM - 然后您可以使用反射来检查类型是否存在。查看更新的答案。
  • 我很想把它放在一个封装类中,这样你就不会在你的代码库中乱扔类型检查。此外,我会将封装类命名为相同的名称:TopographySurface,就在您自己的命名空间中。这样,当您决定放弃对 2013 年的支持时,只需更改您的 using 声明即可。
【解决方案2】:

我取决于您使用的是延迟投标还是提前投标。 后期绑定: -没有编译时警告/错误 - 仅运行时错误

早期投标: - 编译器错误 -运行时错误

【讨论】:

  • 然后呢?它是如何回答问题的?
  • @lauCosma 感谢您的回复,但任一解决方案仍会涉及运行时错误。我想我可以在运行时检查引用是否存在?但如果可能的话,最好在编译时做。
  • 您可以尝试捕获引用...但这仍然是在运行时...所以我认为到目前为止最好的解决方案是运行时错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 2013-11-13
  • 1970-01-01
  • 1970-01-01
  • 2020-05-17
  • 2017-10-22
相关资源
最近更新 更多