是否可以在C#中动态指定外部别名

本文关键字:外部 别名 动态 是否 | 更新日期: 2023-09-27 18:01:04

假设您有两个DLL,其中包含几乎相同的代码。它们之间只有微小的差异,但这些差异足够重要,需要保持不同的库。实际上,在我的特殊情况下,它们是第三方Java库,已经使用IKVM转换为.NET DLL,所以我们不能在不重写代码的情况下将它们合并为一个库。这些表示由外部供应商提供的服务器API的略微不同的版本。

当我们在代码中使用这些库时,我们被迫编写两个完全相同的类,只是我们指定的外部别名不同。

例如:

extern alias Lib1;
namespace MyNamespace
{
    public Class1
    {
        private Lib1::A a = new Lib1::A();
        public Class1()
        {
            this.a.DoStuff();
        }
        // Uses Lib1 extern alias throughout
    }
}
extern alias Lib2;
namespace MyNamespace
{
    public Class2
    {
        private Lib2::A a = new Lib2::A();
        public Class1()
        {
            this.a.DoStuff();
        }
        // Totally identical to Class1, except that it uses Lib2 extern alias throughout
    }
}

Class1中的所有代码都与Class2完全相同。只是别名不同。

当我们想要更新代码时,我们被迫将代码从一个类复制到所有其他类中。然后我们简单地用另一个别名替换一个别名。

有没有一种方法可以创建一个单独的类,并在实例化该类时动态指定要使用的外部别名?

谢谢你的帮助。

是否可以在C#中动态指定外部别名

选项:

  • 针对单个DLL进行构建,然后只切换DLL内容(即使用相同名称构建两个DLL,然后只更改使用的版本(
  • 创建一个具有两个不同实现的接口,其中一个实现与每个库对话

就我个人而言,我可能会选择后者。不,没有"动态外部别名"这样的上下文。

我建议为Lib1.A和Lib2.A定义一个接口。

然后按照以下实现Class2

    public MyClass
    {
        private readonly ILib _lib; 
        public Class2(ILib lib)
        {
          _lib = lib
        }
        public MyMethod()
        {
            _lib.DoStuff();
        }                
    }

您可以将其称为new MyClass(new Lib1::A()).MyMethod()new MyClass(new Lib2::A()).MyMethod()

注入ILib依赖项也将有助于对其进行单元测试。

我找到的最好的方法是使用更高级别的命名空间。。。这样,您就可以在一个类中确定要调用哪个,然后调用正确的。

Jon Skeet回答后,您可以创建一个抽象类,实现两个类之间所有常见的"重复"代码,并将需要唯一代码的方法标记为抽象。

这样,您就不会在任何地方重复代码,而且由于多态性,更改上下文一点也不困难。