How to access items inside nested records and polymorphic hierarchies in C++

1 Answer

0 votes
using System;

namespace ShapeApp
{
    // 1. Define metadata using an immutable record
    public record Metadata(string Name, bool IsActive);

    // 2. Define a discriminated union base record (C# algebraic data type pattern)
    public abstract record Dimension
    {
        public sealed record Circle(float Radius) : Dimension();
        public sealed record Rectangle(float Width, float Height) : Dimension();
    }

    // 3. Define the main container record holding ID, metadata, and the variant dimension
    public record Shape(int Id, Metadata Metadata, Dimension Dimension);

    public class Program
    {
        /// <summary>
        /// Safely accesses and prints items from nested records and variant types
        /// using modern C# pattern matching switch expressions.
        /// </summary>
        /// <param name="shape">The shape object to inspect.</param>
        public static void PrintShapeProperties(Shape shape)
        {
            if (shape == null) {
                Console.WriteLine("Error: Received null shape.");
                return;
            }

            // Accessing nested record properties directly via auto-synthesized getters
            Console.WriteLine($"Shape ID: {shape.Id}");
            Console.WriteLine($"Shape Name: {shape.Metadata.Name}");
            Console.WriteLine($"Status: {(shape.Metadata.IsActive ? "Active" : "Inactive")}");

            // Switch expressions with type patterns handle variant types safely and exhaustively
            string dimensionDetails = shape.Dimension switch
            {
                Dimension.Circle c => $"Type: Circle\nRadius: {c.Radius}",
                Dimension.Rectangle r => $"Type: Rectangle\nWidth: {r.Width}, Height: {r.Height}",
                _ => throw new ArgumentOutOfRangeException(nameof(shape.Dimension), "Unknown dimension type")
            };

            Console.WriteLine(dimensionDetails);
            Console.WriteLine("------------------------------------");
        }

        public static void Main(string[] args)
        {
            // Initialize a Circle shape using target-typed new expressions
            Shape myCircle = new(
                101,
                new("Unit Circle", true),
                new Dimension.Circle(5.5f)
            );

            // Initialize a Rectangle shape
            Shape myRectangle = new(
                102,
                new("Bounding Box", false),
                new Dimension.Rectangle(10.0f, 20.0f)
            );

            // Print properties
            PrintShapeProperties(myCircle);
            PrintShapeProperties(myRectangle);
        }
    }
}


/*
run:

Shape ID: 101
Shape Name: Unit Circle
Status: Active
Type: Circle
Radius: 5.5
------------------------------------
Shape ID: 102
Shape Name: Bounding Box
Status: Inactive
Type: Rectangle
Width: 10, Height: 20
------------------------------------

*/

 



answered 1 day ago by avibootz

Related questions

...