【问题标题】:Casting Abstract to Interface implemented by Derived将抽象转换为派生实现的接口
【发布时间】:2019-01-11 23:31:04
【问题描述】:

我听说在 c# 中向上转换是在编译时完成的,所以使用起来非常便宜。 但是我有这种情况,我希望转换的类型是抽象的,它不直接实现我希望转换的接口。

这是一个示例:

public interface ISomething
{
   void Method();
}

public abstract class Base { }

public class Derived : Base, ISomething 
{
    public void Method() { }
}

public class OtherDerived : Base, ISomething
{
    public void Method() { }
}

public class SomeClass
{
    private Base[] _baseArray;

    public void SomeMethod()
    {
        foreach (var item in _baseArray)
            ((ISomething) item).Method();
    }
}

显然,我处于_baseArray 的每个项目实际上都是从Base 继承并实现ISomething 的类型的情况。 但是由于我无法确定每个项目在DerivedOtherDerived 或从Base 继承并实现ISomething 的任何其他类型之间是什么类型,因此我必须使用抽象基类型的数组。

当然我可以使用ISomething 的数组,但是我使用 Unity 并且接口在编辑模式下不会被序列化,我需要序列化该数组。

所以,既然上下文在这里,我的问题如下: 将item 转换为ISomething 是否在编译时处理?如果不是,它是否足够便宜,可以经常进行(准确地说是在每一帧)?

感谢您的关注,如果我不是很清楚,对不起,我不是英语,所以这并不容易。

编辑:感谢更好的标题

【问题讨论】:

  • 是否让Base 实现ISomething 允许序列化而不需要强制转换?
  • 是的,但在我的情况下,从Base 继承的类型并不总是实现ISomethingBase 派生类型可以实现许多其他接口(以及许多其他SomeMethod 模式与这些其他接口)。

标签: c# performance interface casting abstract


【解决方案1】:

你可以看到你的 C# 编译成的 IL:SharpLab IL Results

你的循环:

    // loop start (head: IL_0021)
        IL_000d: ldloc.0
        IL_000e: ldloc.1
        IL_000f: ldelem.ref
        IL_0010: stloc.2
        IL_0011: ldloc.2
        IL_0012: castclass ISomething
        IL_0017: callvirt instance void ISomething::Method()
        IL_001c: nop
        // sequence point: hidden
        IL_001d: ldloc.1
        IL_001e: ldc.i4.1
        IL_001f: add
        IL_0020: stloc.1

        IL_0021: ldloc.1
        IL_0022: ldloc.0
        IL_0023: ldlen
        IL_0024: conv.i4
        IL_0025: blt.s IL_000d
    // end loop

Method() 是使用callvirt 调用的,这基本上意味着调度。在这种情况下,这是因为您的对象的具体类型在编译时是未知的。

不过,我不会担心它的性能,除非您分析并发现此特定代码是热点。

【讨论】:

  • 是的,我是这么认为的,感谢您的回答。在这种情况下,它确实似乎没有性能问题,所以我会坚持我这里的内容。
猜你喜欢
  • 2012-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-08
相关资源
最近更新 更多