Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8889187
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T22:12:04+00:00 2026-06-14T22:12:04+00:00

see code snippet public interface I0 { void f0(); } public struct S0:I0 {

  • 0

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#?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T22:12:05+00:00Added an answer on June 14, 2026 at 10:12 pm

    It depends… you specifically say you don’t want a generic class… the only other option is a generic method in a non-generic class. The only other time you can get the compiler to emit a constrained call is if you call ToString(), GetHashCode() or Equals() (from object) on a struct, since those are then constrained – if the struct has an override they will be call; if it doesn’t have an override, they will be callvirt. Which is why you should always override those 3 for any struct ;p But I digress. A simple example would be a utility class with some static methods – extension methods would be an ideal example, since you also get the advantage that the compiler will switch automatically between the public/implicit API and the extension/explicit API, without you ever needing to change code. For example, the following (which shows both an implicit and explicit implementation) has no boxing, with one call and one constrained+callvirt, which will implemented via call at the JIT:

    using System;
    interface IFoo
    {
        void Bar();
    }
    struct ExplicitImpl : IFoo
    {
        void IFoo.Bar() { Console.WriteLine("ExplicitImpl"); }
    }
    struct ImplicitImpl : IFoo
    {
        public void Bar() {Console.WriteLine("ImplicitImpl");}
    }
    static class FooExtensions
    {
        public static void Bar<T>(this T foo) where T : IFoo
        {
            foo.Bar();
        }
    }
    static class Program
    {
        static void Main()
        {
            var expl = new ExplicitImpl();
            expl.Bar(); // via extension method
            var impl = new ImplicitImpl();
            impl.Bar(); // direct
        }
    }
    

    And here’s the key bits of IL:

    .method private hidebysig static void Main() cil managed
    {
        .entrypoint
        .maxstack 1
        .locals init (
            [0] valuetype ExplicitImpl expl,
            [1] valuetype ImplicitImpl impl)
        L_0000: ldloca.s expl
        L_0002: initobj ExplicitImpl
        L_0008: ldloc.0 
        L_0009: call void FooExtensions::Bar<valuetype ExplicitImpl>(!!0)
        L_000e: ldloca.s impl
        L_0010: initobj ImplicitImpl
        L_0016: ldloca.s impl
        L_0018: call instance void ImplicitImpl::Bar()
        L_001d: ret 
    }
    .method public hidebysig static void Bar<(IFoo) T>(!!T foo) cil managed
    {
        .custom instance void [mscorlib]System.Runtime.CompilerServices.ExtensionAttribute::.ctor()
        .maxstack 8
        L_0000: ldarga.s foo
        L_0002: constrained. !!T
        L_0008: callvirt instance void IFoo::Bar()
        L_000d: ret 
    }
    

    One downside of an extension method, though, is that it is doing an extra copy of the struct (see the ldloc.0) on the stack, which might be a problem if it is either oversized, or if it is a mutating method (which you should avoid anyway). If that is the case, a ref parameter is helpful, but note that an extension method cannot have a ref this parameter – so you can’t do that with an extension method. But consider:

    Bar(ref expl);
    Bar(ref impl);
    

    with:

    static void Bar<T>(ref T foo) where T : IFoo
    {
        foo.Bar();
    }
    

    which is:

    L_001d: ldloca.s expl
    L_001f: call void Program::Bar<valuetype ExplicitImpl>(!!0&)
    L_0024: ldloca.s impl
    L_0026: call void Program::Bar<valuetype ImplicitImpl>(!!0&)
    

    with:

    .method private hidebysig static void Bar<(IFoo) T>(!!T& foo) cil managed
    {
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: constrained. !!T
        L_0007: callvirt instance void IFoo::Bar()
        L_000c: ret 
    }
    

    Still no boxing, but now we also never copy the struct, even for the explicit case.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

See code just bellow Our generic interface public interface Repository<INSTANCE_CLASS, INSTANCE_ID_CLASS> { void add(INSTANCE_CLASS
Please see my following code snippet. @Transactional public void saveMembersService(List<Member> list1, List<Member> list2) {
Let's see the following code snippet in Java. public class Main { public static
Let's see the following code snippet in Java. package common; final public class Main
Let's see the following simplest code snippet in Java. final public class Parsing {
Help me understand the following code snippet: (foo.h) class Foo { public: typedef void
I have a code snippet as public class ThreadStates { private static Thread t1
Consider this code snippet: public static void main(String[] args) { int z1 = 0;
Please explain why the following code snippet fails to compile: public class ScjpTest{ static
Here's the code snippet from my Controller... it all starts at my Index. public

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.