Is it safe for structs to implement interfaces?
There are several things going on in this question...
It is possible for a struct to implement an interface, but there are concerns that come about with casting, mutability, and performance. See this post for more details: https://learn.microsoft.com/en-us/archive/blogs/abhinaba/c-structs-and-interface
In general, structs should be used for objects that have value-type semantics. By implementing an interface on a struct you can run into boxing concerns as the struct is cast back and forth between the struct and the interface. As a result of the boxing, operations that change the internal state of the struct may not behave properly.
Structs, Interfaces and Boxing
Yes, it is. Basically whenever you need a reference and you've only got a value type value, the value is boxed.
Here, ISomeInterface
is an interface, which is a reference type. Therefore the value of someVariable
is always a reference, so the newly created struct value has to be boxed.
Why is interface inheritance allowed on a struct and why can a class not be inherited
Interface
is not a reference or value type by itself. Interface
is a contract, which reference or value type subscribe to.
You probably refer to a fact that struct
that inherits from interface
is boxed.
Yes. This is because in C# struct members are defined like virtual
members. And for
virtual members you need to maintain virtual table, so you need a reference type.
Let's do following to prove this:
public interface IStruct {
string Name {get;set;}
}
public struct Derived : IStruct {
public string Name {get;set;}
}
Now, let's call it in this way:
//somewhere in the code
public void ChangeName(IStruct structInterface) {
structInterface.Name = "John Doe";
}
//and we call this function as
IStruct inter = new Derived();
ChangeName(inter);
//HERE NAME IS CHANGED !!
//inter.Name == "John Doe";
This is not something we would expect from value type, but this is exactly as reference types work. So here what happens is that value typed instance of Derived is boxed to reference type constructed on top of IStruct
.
There are performance implications and also misleading behavior, like in this case, of the value type that starts to behave like a reference type.
More on this subject can have a look on:
C#: Structs and Interface
Constrain interface implementations to structs?
Is there any way an interface can be declared so that the implementing type is constrained to be a struct?
No, that is currently not possible and neither is the inverse (ensuring an interface is implemented by a class).
As far as documentation goes the closest thing I was able to find was this Interfaces, Interfaces (c#), Inheritance - Interfaces. I doubt there will be anything on an official MS site simply because (in most cases) there is no documentation on non-existing features (ignoring feature requests or features in progress) and this could be considered a non-existent feature.
Closest excerpt I could find
A class or struct can implement multiple interfaces. ...
Struct vs class implementing an interface
Just like Bharathram Attiyannan answered, variance is simply not supported for value types.
The workaround is simple:
List<FooStruct> listOfFooStruct = new List<FooStruct>();
IEnumerable<IFoo> enumerableOfFoo = listOfFooStruct.Cast<IFoo>();
Navigate to Interface from Implementing Struct in GoLand
Yes, GoLand will allow you to jump to the interface that a struct implements. It works in the inverse too; it'll show you all of the types that implement an interface.
Related Topics
How to Iterate Through a Datatable
Total Number of Items Defined in an Enum
How to Redirect to Index from Another Controller
Httpcontext.Current Is Null When Unit Test
Save Detached Entity in Entity Framework 6
Determine Operating System in .Net Core
How to Render an ASP.NET MVC View in PDF Format
How to Click a Button in a Webbrowser Control
Read a Xml (From a String) and Get Some Fields - Problems Reading Xml
What Does Linq Return When the Results Are Empty
Only Primitive Types or Enumeration Types Are Supported in This Context
Execute Multiple Queries in Single Oracle Command in C#
Execute Unit Tests Serially (Rather Than in Parallel)
Entity Framework Queryable Async
Best Practices: Throwing Exceptions from Properties