5

我有一个 C# 接口,其中某些方法参数声明为object类型。但是,传递的实际类型可能因实现接口的类而异:

public interface IMyInterface
{
    void MyMethod(object arg);
}

public class MyClass1 : IMyInterface
{
    public void MyMethod(object arg)
    {
        MyObject obj = (MyObject) arg;
        // do something with obj...
    }
}

public class MyClass2 : IMyInterface
{
    public void MyMethod(object arg)
    {
        byte[] obj = (byte[]) arg;
        // do something with obj...
    }
}

MyClass2 的问题在于byte[]to 和 from的转换object装箱和拆箱,这是影响性能的计算量大的操作。

通用接口解决这个问题会避免装箱/拆箱吗?

public interface IMyInterface<T>
{
    void MyMethod(T arg);
}

public class MyClass1 : IMyInterface<MyObject>
{
    public void MyMethod(MyObject arg)
    {
        // typecast no longer necessary
        //MyObject obj = (MyObject) arg;
        // do something with arg...
    }
}

public class MyClass2 : IMyInterface<byte[]>
{
    public void MyMethod(byte[] arg)
    {
        // typecast no longer necessary
        //byte[] obj = (byte[]) arg;
        // do something with arg...
    }
}

这是如何在 .NET 与 Mono 中实现的?在这两个平台上都会有任何性能影响吗?

谢谢!

4

6 回答 6

14

您将在 Mono 中获得与在 .NET 中相同的好处。

我们强烈建议您总体上使用 Mono 1.9 或 Mono 2.0 RCx,因为泛型支持仅在 1.9 中成熟。

于 2008-09-26T14:54:18.457 回答
11

MyClass2 的问题是 byte[] 与 object 的转换是装箱和拆箱,这是影响性能的计算量大的操作。

数组类型不涉及装箱,即使是值类型元素也是如此。数组是一种引用类型。

(byte[]) arg 的开销充其量是最小的。

于 2008-09-26T14:50:07.110 回答
8

我不确定它是如何在单声道中实现的,但通用接口会有所帮助,因为编译器会为使用的每种不同类型创建一个特定类型的新函数(在内部,它可以利用相同的生成函数) . 如果生成了特定类型的函数,则无需对该类型进行装箱/拆箱。

这就是为什么 Collections.Generic 库在 .NET 2.0 中大受欢迎的原因,因为集合不再需要装箱并且变得更加高效。

于 2008-09-26T14:51:19.557 回答
2

是的,在 .Net 中(MS 不确定单声道)泛型是在编译时实现的,因此根本没有装箱或拆箱。与 Java 泛型形成对比,后者是仅在后台为您执行强制转换的语法糖(至少曾经是这种方式)。泛型的主要问题是您不能多态地处理泛型容器,但这有点偏离您的主题:-)

于 2008-09-26T15:33:57.940 回答
1

我无法与 Mono 交谈,但使用通用接口应该可以解决 MS 运行时中的装箱/拆箱问题。

于 2008-09-26T14:50:20.153 回答
0

鉴于您使用的是最新版本的单声道,如果可以,请使用 2.0。

Mono 上的通用接口性能非常好,与常规接口调度配对。

通用虚拟方法的调度[1] 在所有已发布的 mono 版本上都很糟糕,它在 1.9 中得到了改进。

这个问题并没有那么糟糕,因为泛型虚拟方法的性能问题已经在预定于今年年底发布的下一个 mono (2.2) 版本中得到修复。

[1] 通用虚拟方法类似于:

公共接口 Foo {

  void Bla<T> (T a, T b);

}

于 2008-10-06T22:20:35.623 回答