Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there other ways of calling an interface method of a struct without boxing except in generic classes?

Tags:

c#

il

see code snippet

public interface I0
{
    void f0();
}
public struct S0:I0
{
    void I0.f0()
    {

    }
}
public class A<E> where E :I0
{
    public E e;
    public void call()
    {
        e.f0();
    }
}

here is IL code for call()

.maxstack 8
L_0000: ldarg.0 
L_0001: ldflda !0 Temp.A`1<!E>::e
L_0006: constrained !E
L_000c: callvirt instance void Temp.I0::f0()
L_0011: ret 

see reference for constrained

The constrained prefix can also be used for invocation of interface methods on value types, because the value type method implementing the interface method can be changed using a MethodImpl. If the constrained prefix is not used, the compiler is forced to choose which of the value type's methods to bind to at compile time. Using the constrained prefix allows the MSIL to bind to the method that implements the interface method at run time, rather than at compile time.

That means it will call one method containing interface method code of f0 without boxing the struct.

Do any other ways caling interface method without boxing exist as above GenericClass in C#?

like image 860
Vince Avatar asked Nov 26 '12 04:11

Vince


People also ask

Can you call interface methods?

In order to call an interface method from a java program, the program must instantiate the interface implementation program. A method can then be called using the implementation object.

Can struct have interface?

An interface can't be instantiated directly. Its members are implemented by any class or struct that implements the interface. A class or struct can implement multiple interfaces. A class can inherit a base class and also implement one or more interfaces.

Can we implement interface in struct C#?

A class or a struct can implement one or more interfaces implicitly or explicitly. Use public modifier when implementing interface implicitly, whereas don't use it in case of explicit implementation. Implement interface explicitly using InterfaceName.


1 Answers

Since interfaces are treated as reference types, there is no way to call a method on a struct referred to by an interface without having to box the underlying struct first.

When using a generic method enforcing the type to implement the interface, the C# compiler simply lifts the actual implementation details and hence the calling convention to the runtime. Luckily the C# compiler is smart enough to instruct the JIT compiler that the subjected type does implement interface X and might be a struct. With this information the JIT compiler can figure out how to invoke method Y declared by interface X.

The above trick is not usable for a non-generic method call since there is no practical way for the JIT compiler to figure out the actual type represented by the argument X when X is a non sealed class or interface. Hence, there is no way for the C# compiler to generate JIT that deals with a lookup table in case the type represented by the interface passed is a non-sealed class and a direct method invocation that deals with structs and sealed classes.

When using dynamic you can, in theory, prevent boxing however the loss of performance for introducing the DLR will likely yield no benefit at all.

like image 96
Polity Avatar answered Oct 20 '22 20:10

Polity