跨程序集模拟分部类

本文关键字:模拟 程序集 | 更新日期: 2023-09-27 18:00:52

为了便于使用,我正试图将许多辅助类组合到一个通用的父类中。例如,在我的应用程序中,我想进行

Tools.StringTool.foo(..)
Tools.NumberTool.bar(..)
Tools.NetworkTool.something(...)

这里的想法是将所有工具组织在一个通用的tools类下,这样当我键入"tools"时,intellisense就可以将它们全部显示出来

在父静态分部类tools下定义所有工具效果良好,但不适用于其他程序集中的tools。

我试图通过将父Tools类替换为命名空间X.Y.Tools来模拟程序集之间的静态分部类,但对于在X.Y命名空间之外编写的代码,我需要在使用每个工具之前对其进行完全限定。

即应用程序内代码

  Tools.MyTool(..) // won't compile
  X.Y.Tools.MyTool(...) // will compile but ugly

有什么建议我可以解决这个问题或组织工具的替代方法吗?

跨程序集模拟分部类

在这种情况下,您可以使用扩展方法。导入命名空间时,在命名空间内的类中定义的所有扩展方法都可用。

通过这种方式,你会有像MyUtilityNamespace.MyClassInAssembly1MyUtilityNamespace.MyClassInAssembly2这样的静态类,它们都为一个类实例提供了扩展方法,但这与获得该类实例有关,就像这样:

// in central assembly
class Tool {
    private static Tool _t = new Tool();
    public static Tool T { get { return _t; } }
}
// in utility assembly 1
public static class MyExtensionClassInAssembly1 {
    public static void SomeUtilityMethodX(this Tool tool, Object arg1, Object arg2) {
        // do something
    }
}
// in utility assembly 2
public static class MyExtensionClassInAssembly2 {
    public static void SomeUtilityMethodY(this Tool tool) {
        // do something
    }
}

你会这样使用它:

Tool.T.SomeUtilityMethodX( Tool.T.SomeUtilityMethodY(), null );

这并不漂亮,但意味着您只需要导入一次名称空间,并且Tool.T是常量,不需要记住StringToolNetworkTool

另一种选择是使用名称空间或类型别名,但这很费力,因为您需要在每个源文件上指定using Tools = X.Y.Tools.MyTool;行。

事实证明,最简单的方法就是简单地使用名称空间

 // in project 1
 namespace Tools {
      public static class NetworkTool {
      }
 }
 // in project 2
 namespace Tools {
      public static class FileTool {
      }
 }
 // in client code (references both projects)
 Tools.NetworkTool.SomeMethod();
 Tools.FileTool.SomeMethod()