是否可以在汇编A中在汇编G和汇编M的类型之间添加隐式运算符?

本文关键字:汇编 添加 之间 类型 运算符 是否 | 更新日期: 2023-09-27 18:06:38

假设有一个图形API G不想依赖于任何外部数学库,因此将其所有向量参数定义为裸结构体(就像SharpDX对其原始类型所做的那样)。

让有数学库M

开发人员希望在汇编程序A中提供隐式运算符,以便在数学库M的完整类型与图形API G的原始类型之间进行转换(SharpDX的另一个示例,但在这种情况下,运算符定义在M而不是A中)。请注意,这两种类型具有完全相同的内存表示。


很显然,c#语言没有办法提供这样的操作符。最接近的是扩展方法,但是用户仍然需要调用一个额外的方法来进行转换。

是否有可能或者有这样的操作符的样本被添加通过IL重写?根据我有限的知识,我认为这是可能的,但希望能得到更多的反馈。

谢谢!

是否可以在汇编A中在汇编G和汇编M的类型之间添加隐式运算符?

您可以通过重写两个库之一的IL来实现这一点,具体来说,您可以向类型添加隐式操作符(并且在此过程中还添加对另一个库的依赖)。

但我认为这样做是一个坏主意:这意味着你需要使用你自己的库版本(即你不能只使用NuGet的版本),每次你想升级它,你都需要再次运行IL重写器。

对我来说,这听起来像是太多的工作,只是为了你可以写Foo(bar)而不是Foo(bar.ToBaz())

扩展我的评论,这里有一个过于简化的例子。要求本质上是能够互换地使用这两种类型。我们如何做到这一点?通过添加第三种类型。然后,根据新类型定义应用程序中的所有逻辑,并封装对外部库的调用。

// External Assemblies A and B define the following types:
// Assembly A
public class X
{
    public string Name { get; set; }
    public static void SomeFunction(X item)
    {
        Console.WriteLine($"X.{item.Name}");
    }
}
// Assembly B
public class Y
{
    public string Name { get; set; }
    public static void SomeFunction(Y item)
    {
        Console.WriteLine($"Y.{item.Name}");
    }
}
// We would create an implicit intermediary in intermediate assembly C
// Assembly C
public class Z
{
    public string Name { get; set; }
    public static implicit operator Z(X input) => new Z { Name = input.Name };
    public static implicit operator X(Z input) => new X { Name = input.Name };
    public static implicit operator Z(Y input) => new Z { Name = input.Name };
    public static implicit operator Y(Z input) => new Y { Name = input.Name };
}
public void PushToX(Z thing) => X.SomeFunction(thing);
public void PushToY(Z thing) => Y.SomeFunction(thing);
public void DoThing(Z thing)
{
    Console.WriteLine(thing.Name);
}
public void Main()
{
    var a = new X { Name = "A" };
    var b = new Y { Name = "B" };
    DoThing(a);
    DoThing(b);
    PushToX(a);
    PushToY(a);
    PushToX(b);
    PushToY(b);
    //A
    //B
    //X.A
    //Y.A
    //X.B
    //Y.B
}