I have a structure something like this
struct MyStructure
:IFoo
{
}
and a method like this:
public BarThisFoo(IFoo a)
{
}
my question is does passing the structure into that method "box" the structure, thus causing a garbage allocation?
Addendum: Before anyone says it, garbage collection is not free in this application, it's actually very sensitive to garbage collections, so allocation free code is important.
In addition, you must use an interface if you want to simulate inheritance for structs, because they can't actually inherit from another struct or class. You define an interface by using the interface keyword as the following example shows. The name of an interface must be a valid C# identifier name.
We can define interfaces considering the different actions that are common between multiple types. In Go, we can automatically infer that a struct (object) implements an interface when it implements all its methods.
Structs and interfaces are Go's way of organizing methods and data handling. Where structs define the fields of an object, like a Person's first and last name. The interfaces define the methods; e.g. formatting and returning a Person's full name.
To avoid boxing you can use generics with constraints:
struct MyStructure
:IFoo
{
}
public void BarThisFoo<T>(T a) where T : IFoo
{
}
See J. Richter CLR via C#, 2nd edition, chapter 14: Interfaces, section about Generics and Interface Constraints.
EDIT:
Example code
using System;
using System.Collections;
interface IFoo {
void Foo();
}
struct MyStructure : IFoo {
public void Foo() {
}
}
public static class Program {
static void BarThisFoo<T>(T t) where T : IFoo {
t.Foo();
}
static void Main(string[] args) {
MyStructure s = new MyStructure();
BarThisFoo(s);
}
}
IL code for method Main doesn't contain any box instructions:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 15 (0xf)
.maxstack 1
.locals init ([0] valuetype MyStructure s)
IL_0000: ldloca.s s
IL_0002: initobj MyStructure
IL_0008: ldloc.0
IL_0009: call void Program::BarThisFoo<valuetype MyStructure>(!!0)
IL_000e: ret
} // end of method Program::Main
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With