Struct Embedding in C#
C# supports composition of types through inheritance and interfaces. While it doesn’t have a direct equivalent to Go’s struct embedding, we can achieve similar functionality using inheritance and interfaces.
using System;
// Base class
public class Base
{
public int Num { get; set; }
public string Describe()
{
return $"base with num={Num}";
}
}
// Container class inherits from Base
public class Container : Base
{
public string Str { get; set; }
}
// Interface for describing
public interface IDescriber
{
string Describe();
}
class Program
{
static void Main()
{
// Creating an instance of Container
var co = new Container
{
Num = 1,
Str = "some name"
};
// We can access the base's fields directly on co
Console.WriteLine($"co={{num: {co.Num}, str: {co.Str}}}");
// We can also access the base's fields using the base keyword
Console.WriteLine($"also num: {co.Num}");
// Since Container inherits from Base, it has access to Base's methods
Console.WriteLine($"describe: {co.Describe()}");
// Container implements IDescriber interface implicitly through inheritance
IDescriber d = co;
Console.WriteLine($"describer: {d.Describe()}");
}
}
When you run this program, you’ll see the following output:
co={num: 1, str: some name}
also num: 1
describe: base with num=1
describer: base with num=1
In C#, we use inheritance to achieve a similar effect to Go’s struct embedding. The Container
class inherits from the Base
class, which allows it to access all public members of Base
.
We define an IDescriber
interface that declares the Describe
method. Since Base
implements this method and Container
inherits from Base
, Container
automatically implements the IDescriber
interface.
This example demonstrates how C# uses inheritance and interfaces to create a composition of types, allowing for code reuse and polymorphism. While the syntax and exact mechanisms differ from Go’s struct embedding, the end result is similar in terms of functionality and code organization.