C# 将抽象转换为由派生语言实现的接口

C# 将抽象转换为由派生语言实现的接口,c#,performance,interface,casting,abstract,C#,Performance,Interface,Casting,Abstract,我听说在c#中,向上转换是在编译时完成的,所以使用起来非常便宜。 但是我有这样一种情况,我希望转换的类型是抽象的,它没有直接实现我希望转换的接口 以下是一个示例: public interface ISomething { void Method(); } public abstract class Base { } public class Derived : Base, ISomething { public void Method() { } } public cla

我听说在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();
    }
}
显然,我所处的情况是,
\u baseArray
的每一项实际上都是继承自
Base
并实现
ISomething
的类型。 但由于我无法确定
派生的
其他派生的
或继承自
基的
并实现
等轴物
的任何其他类型之间的每个项都是什么类型,因此我必须使用抽象基类型的数组

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

因此,现在这里有了背景,我的问题如下: 是否在编译时处理将
转换为
ISomething
的操作?如果不是,那么它是否足够便宜,可以经常(准确地说是在每一帧上)使用呢

谢谢你的关注,如果我不是非常清楚,我不是英语,所以这不是很容易


编辑:感谢您提供了更好的标题

您可以看到您的C#编译成的IL:

您的循环:

    // 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
调用的,这基本上意味着分派。在这种情况下,这是因为编译时不知道对象的特定类型


不过,我不会担心它的性能,除非你分析了这段代码,你会发现这段代码是一个热点。

使用
Base
实现
ISomething
是否允许序列化而不需要强制转换?是的,但在我的情况下,从
Base
继承的类型并不总是实现
ISomething
。我有很多其他接口(还有很多其他
SomeMethod
模式和这些其他接口),
Base
派生类型可以实现。是的,我想是的,谢谢你的回答。在这种情况下,它似乎确实没有性能问题,所以我将继续使用这里的内容。