【问题标题】:Conditionally including code based on the existence of a class基于类的存在有条件地包含代码
【发布时间】:2011-01-10 20:20:11
【问题描述】:

我有两个函数以两种不同的方式做同样的事情。每个都使用不同的类来完成任务:

void functionA()
{
  ClassA a = new ClassA();
  a.doWork();
}

void functionB()
{
  ClassB b = new ClassB();
  b.doSomething();
}

这一切都在一个自包含的 HttpHandler 中,可以在任何项目和工作中删除 - 至少这是目标。 FunctionA 将是首选的做事方式, FunctionB 是后备。 ClassA 可能不存在于给定项目中,ClassB 将始终存在。

有没有办法在运行时检测 ClassA 是否存在使用 functionA,如果不使用 fcuntionB。如果 ClassA 不存在,还有没有办法编译它?我可以用预处理器的东西来做这件事吗(即我可以在编译时告诉我要包含哪些内容吗?)

【问题讨论】:

    标签: c# c-preprocessor


    【解决方案1】:

    通常情况下,通过Inversion of Control 处理此类情况比尝试确定类的存在要好得多。

    与其寻找“ClassA”和“ClassB”,不如提供2个可以实现的接口。然后,您可以使用Dependency Injection 尝试注入IInterfaceA 的实例,如果失败,请改用IInterfaceB 的实例。

    一篇好文章可能是Martin Fowler's article on IoC。此外,您可能想查看 Managed Extensibility Framework(现在包含在 .NET 4 中),这使得这在 C# 中变得非常容易。

    【讨论】:

      【解决方案2】:

      如果你必须使用预处理器 #if#define 指令来做,那么在 ClassA 中添加

      #define ClassA
      

      在你的HttpHandler 添加

      #if ClassA
        void function() { ClassA a = new ClassA(); a.doWork(); }
      #else
        void function() { ClassB b = new ClassB(); b.doSomething(); }
      #endif
      

      如果可能,最好使用dependency injection 并将其传递给HttpHandler 的构造函数。

      【讨论】:

        【解决方案3】:

        您可以使用 partial 关键字将您的课程分成两个文件:

        // MyClass.cs -- include this into every project
        public partial class MyClass {
            public void functionB() { ClassB b = new ClassB(); b.doSomething(); }
        }
        
        // MyClass.functionA.cs -- include only into projects that have ClassA
        public partial class MyClass {
            public void functionA() { ClassA a = new ClassA(); a.doWork(); }
        }
        

        我们在代码中的几个地方执行此操作。我喜欢“BaseName.Specialty.cs”命名约定,因为解决方案资源管理器会自动将 MyClass.functionA.cs 显示为嵌套在 MyClass.cs 下的子节点,就像处理 .designer.cs 文件一样。

        【讨论】:

          【解决方案4】:

          您可以使用反射 (http://msdn.microsoft.com/en-us/library/f7ykdhsy(v=vs.71).aspx)。特别是 System.Reflection.Module,它可以返回模块中可用类型的列表 (http://msdn.microsoft.com/en-US/library/system.reflection.module.gettypes(v=VS.80).aspx)。我想一旦知道存在哪种类型,您就可以简单地进行转换。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-08-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-11-16
            • 1970-01-01
            相关资源
            最近更新 更多