Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Details on what happens when a struct implements an interface

I recently came across this Stackoverflow question: When to use struct?

In it, it had an answer that said something a bit profound:

In addition, realize that when a struct implements an interface - as Enumerator does - and is cast to that implemented type, the struct becomes a reference type and is moved to the heap. Internal to the Dictionary class, Enumerator is still a value type. However, as soon as a method calls GetEnumerator(), a reference-type IEnumerator is returned.

Exactly what does this mean?

If I had something like

struct Foo : IFoo 
{
  public int Foobar;
}

class Bar
{
  public IFoo Biz{get; set;} //assume this is Foo
}

...

var b=new Bar();
var f=b.Biz;
f.Foobar=123; //What would happen here
b.Biz.Foobar=567; //would this overwrite the above, or would it have no effect?
b.Biz=new Foo(); //and here!?

What exactly are the detailed semantics of a value-type structure being treated like a reference-type?

like image 641
Earlz Avatar asked Mar 04 '13 17:03

Earlz


People also ask

How can a struct implement an interface?

A class or struct can implement multiple interfaces, but a class can only inherit from a single class. For more information about abstract classes, see Abstract and Sealed Classes and Class Members. Interfaces can contain instance methods, properties, events, indexers, or any combination of those four member types.

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.

What does implementing an interface mean?

Implementing an interface means to actually write some code to fulfill the description of the interface, in terms of function names, attributes and return values.

Is a struct an interface?

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.


2 Answers

Every declaration of a structure type really declares two types within the Runtime: a value type, and a heap object type. From the point of view of external code, the heap object type will behave like a class with a fields and methods of the corresponding value type. From the point of view of internal code, the heap type will behave as though it has a field this of the corresponding value type.

Attempting to cast a value type to a reference type (Object, ValueType, Enum, or any interface type) will generate a new instance of its corresponding heap object type, and return a reference to that new instance. The same thing will happen if one attempts to store a value type into a reference-type storage location, or pass it as a reference-type parameter. Once the value has been converted to a heap object, it will behave--from the point of view of external code--as a heap object.

The only situation in which a value type's implementation of an interface may be used without the value type first being converted to a heap object is when it's passed as a generic type parameter which has the interface type as a constraint. In that particular situation, interface members may be used on the value type instance without its having to be converted to a heap object first.

like image 125
supercat Avatar answered Oct 16 '22 18:10

supercat


Read about boxing and unboxing (search the internet). For example MSDN: Boxing and Unboxing (C# Programming Guide).

See also the SO thread Why do we need boxing and unboxing in C#?, and the threads linked to that thread.

Note: It is not so important if you "convert" to a base class of the value type, as in

object obj = new Foo(); // boxing

or "convert" to an implemented interface, as in

IFoo iFoo = new Foo(); // boxing

The only base classes a struct has, are System.ValueType and object (including dynamic). The base classes of an enum type are System.Enum, System.ValueType, and object.

A struct can implement any number of interfaces (but it inherits no interfaces from its base classes). An enum type implements IComparable (non-generic version), IFormattable, and IConvertible because the base class System.Enum implements those three.

like image 34
Jeppe Stig Nielsen Avatar answered Oct 16 '22 18:10

Jeppe Stig Nielsen