IComparableScenarioQuestions

C# Question Bank

C# IComparable | Warm‑up (with hidden reference answer) + 10 Scenario Questions (5 Moderate + 5 Complex) — Questions Only

Instruction: Students should implement ONLY the methods marked with // ✅ TODO in Q2–Q11.
Warm‑up: Q1 includes a reference answer behind a button to cover key options of IComparable (contract, null handling, multi-field compare, default Sort, custom ordering).
All other questions contain NO answers and remain fully visible by default (boilerplate + scenario + code).
Warm‑up: 1 Moderate: 5 Complex: 5 Coverage: CompareTo contract, null handling, multi-field sort, generic constraints, semantic versioning, natural sort, top‑K, overlaps, SortedSet determinism, custom comparer fallback
1

Warm‑up: Implement IComparable<T> for Support Tickets (with reference answer)

IComparable<T>CompareToMulti-field sortNull handlingSort()Warm-up

Warm‑up (with answer): You will implement IComparable<T> for a custom type and verify sorting behavior. This warm-up covers: - CompareTo contract: return -1 / 0 / +1 - Multi-field comparison (Primary: Priority, Secondary: CreatedAt, Tertiary: TicketId) - Null handling - Ascending order vs custom descending sort using Comparer - Using List<T>.Sort() (default uses IComparable<T>) - Using OrderBy(...) and ThenBy(...) ✅ The warm-up includes a reference answer (hidden behind a button).

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console, DateTime
using System.Collections.Generic;                                    // List, Comparer
using System.Globalization;                                         // parsing
using System.Linq;                                                  // LINQ

namespace ItTechGenie.M1.IComparable.WarmUp
{
    // Ticket model that can be sorted (default) using IComparable<Ticket>
    public class SupportTicket : IComparable<SupportTicket>          // IComparable<T> enables Sort()
    {
        public string TicketId { get; }                              // unique id (may contain spaces/unicode)
        public int Priority { get; }                                 // lower number => higher priority
        public DateTime CreatedAt { get; }                            // created time
        public string Title { get; }                                  // message/title

        public SupportTicket(string ticketId, int priority, DateTime createdAt, string title) // constructor
        {
            TicketId = ticketId;                                     // assign id
            Priority = priority;                                     // assign priority
            CreatedAt = createdAt;                                   // assign time
            Title = title;                                           // assign title
        }

        // ✅ Warm-up TODO: Student can compare with the reference answer (below)
        public int CompareTo(SupportTicket? other)                    // contract: -1/0/+1
        {
            // TODO:
            // 1) null other => current is "greater" or "after" (return 1)
            // 2) Primary: Priority ascending (1 before 2)
            // 3) Secondary: CreatedAt ascending (earlier first)
            // 4) Tertiary: TicketId ordinal (string compare)
            throw new NotImplementedException();
        }

        public override string ToString()                             // print
            => $"{Priority} | {CreatedAt:HH:mm:ss} | {TicketId} | {Title}";
    }

    internal class Program
    {
        static void Main()
        {
            // sample tickets (hard-coded for warm-up)
            var tickets = new List<SupportTicket>                     // list of comparable tickets
            {
                new SupportTicket("TKT- 001 ✅", 2, DateTime.Parse("2026-02-18 10:05:02"), "Login fail!@#"),
                new SupportTicket("TKT-α12", 1, DateTime.Parse("2026-02-18 10:04:59"), "Payment ₹ 1,999.25"),
                new SupportTicket("TKT-β77", 2, DateTime.Parse("2026-02-18 10:05:02"), "Timeout α/β"),
                new SupportTicket("TKT- 001 ✅", 2, DateTime.Parse("2026-02-18 10:05:02"), "Duplicate id")
            };

            // 1) Default sort uses IComparable<T> (CompareTo)
            tickets.Sort();                                           // relies on CompareTo

            Console.WriteLine("Default Sort (Priority, CreatedAt, TicketId):");
            tickets.ForEach(t => Console.WriteLine(t));               // print sorted list

            // 2) Descending sort example using Comparer (not IComparable)
            var desc = tickets.OrderByDescending(t => t.Priority)      // higher priority number first
                              .ThenBy(t => t.CreatedAt)               // then by time
                              .ToList();

            Console.WriteLine("\nCustom Sort (Priority DESC, CreatedAt ASC):");
            desc.ForEach(t => Console.WriteLine(t));
        }
    }
}

Warm‑up Reference Answer (Conceptual)

Reference CompareTo implementation (key points): - If other is null: return 1 (current comes after null). - Compare Priority first (ascending): Priority.CompareTo(other.Priority). - If equal: compare CreatedAt (ascending): CreatedAt.CompareTo(other.CreatedAt). - If equal: compare TicketId (ordinal): string.Compare(TicketId, other.TicketId, StringComparison.Ordinal). - Return first non-zero result; otherwise return 0. This ensures deterministic sorting when multiple fields are equal.

2

Sort Product Catalog — IComparable<Product> (SKU then Price)

IComparable<T>SortStringComparisonModerate

Scenario: Your e-commerce catalog must sort products consistently for display and caching. What to implement: - Product.CompareTo(Product? other) Rules: - Null other: current comes after (return 1) - Primary: SKU (ordinal, trim spaces) - Secondary: Price ascending - Tertiary: Name (case-insensitive) ✅ Implement ONLY the TODO method.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console
using System.Collections.Generic;                                    // List

namespace ItTechGenie.M1.IComparable.Q2
{
    public class Product : IComparable<Product>                      // comparable for Sort()
    {
        public string Sku { get; }                                   // key (may contain spaces)
        public string Name { get; }                                  // display name
        public decimal Price { get; }                                // price

        public Product(string sku, string name, decimal price)        // constructor
        {
            Sku = sku;                                               // assign
            Name = name;                                             // assign
            Price = price;                                           // assign
        }

        // ✅ TODO: Student must implement only this method
        public int CompareTo(Product? other)
        {
            // TODO:
            // - handle null
            // - compare Sku.Trim() using StringComparison.Ordinal
            // - then Price
            // - then Name (ignore case)
            throw new NotImplementedException();
        }

        public override string ToString() => $"{Sku} | {Name} | ₹{Price}";
    }

    internal class Program
    {
        static void Main()
        {
            var list = new List<Product>
            {
                new Product(" SKU-β77  ", "Headphones ✅", 7999m),
                new Product("SKU-α12", "Laptop Stand", 1299.50m),
                new Product("SKU-α12", "Laptop stand", 1299.50m),
                new Product("SKU-!@#", "Cable 2m", 499m),
            };

            list.Sort();                                             // uses CompareTo
            list.ForEach(p => Console.WriteLine(p));
        }
    }
}
3

Generic Min/Max Utility — where T : IComparable<T>

GenericsIComparable<T>ConstraintsModerate

Scenario: A reusable utility must find min and max values safely for any comparable type. What to implement: - RangeUtil.GetMinMax<T>(IEnumerable<T> items) -> (T min, T max) Rules: - Generic constraint: where T : IComparable<T> - Throw ArgumentException if items empty - Must work for int, DateTime, and custom types implementing IComparable<T> ✅ Implement ONLY the TODO method.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console
using System.Collections.Generic;                                    // IEnumerable, List

namespace ItTechGenie.M1.IComparable.Q3
{
    public static class RangeUtil
    {
        // ✅ TODO: Student must implement only this method
        public static (T min, T max) GetMinMax<T>(IEnumerable<T> items) where T : IComparable<T>
        {
            // TODO:
            // - validate items not null
            // - iterate once
            // - initialize min/max from first element
            // - use CompareTo to update
            throw new NotImplementedException();
        }
    }

    internal class Program
    {
        static void Main()
        {
            var ints = new List<int> { 5, 1, 9, 2, 2 };
            var mm1 = RangeUtil.GetMinMax(ints);
            Console.WriteLine($"Int Min={mm1.min}, Max={mm1.max}");

            var dates = new List<DateTime> { DateTime.Parse("2026-02-18"), DateTime.Parse("2026-01-01"), DateTime.Parse("2026-12-31") };
            var mm2 = RangeUtil.GetMinMax(dates);
            Console.WriteLine($"Date Min={mm2.min:yyyy-MM-dd}, Max={mm2.max:yyyy-MM-dd}");
        }
    }
}
4

Normalize & Sort Usernames — Comparisons with Null/Whitespace

IComparableString normalizationEdge casesModerate

Scenario: A user export file contains usernames with extra spaces and mixed casing. You must sort users consistently and safely. What to implement: - User.CompareTo(User? other) Rules: - Null user: current after (return 1) - Normalize username: Trim, collapse multiple spaces, treat null/empty as "" (empty) - Primary: normalized username (case-insensitive) - Secondary: CreatedAt ascending ✅ Implement ONLY the TODO method.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console, DateTime
using System.Collections.Generic;                                    // List
using System.Text.RegularExpressions;                                // Regex

namespace ItTechGenie.M1.IComparable.Q4
{
    public class User : IComparable<User>                            // comparable user
    {
        public string? Username { get; }                              // may be null/empty
        public DateTime CreatedAt { get; }                             // timestamp

        public User(string? username, DateTime createdAt)
        {
            Username = username;
            CreatedAt = createdAt;
        }

        private static string Normalize(string? s)                    // helper normalize
        {
            // simple normalization (can be used inside CompareTo)
            if (string.IsNullOrWhiteSpace(s)) return "";              // treat null/empty
            s = s.Trim();                                             // trim ends
            s = Regex.Replace(s, @"\s+", " ");                        // collapse spaces
            return s;
        }

        // ✅ TODO: Student must implement only this method
        public int CompareTo(User? other)
        {
            // TODO:
            // - handle null other
            // - compare normalized username ignoring case
            // - then CreatedAt ascending
            throw new NotImplementedException();
        }

        public override string ToString() => $"{Normalize(Username)} | {CreatedAt:HH:mm}";
    }

    internal class Program
    {
        static void Main()
        {
            var list = new List<User>
            {
                new User("  Sana   Suresh ✅  ", DateTime.Parse("2026-02-18 10:05")),
                new User("ravi#1", DateTime.Parse("2026-02-18 10:01")),
                new User("", DateTime.Parse("2026-02-18 10:02")),
                new User("Arjun α/β", DateTime.Parse("2026-02-18 10:03")),
            };

            list.Sort();                                              // uses CompareTo
            list.ForEach(u => Console.WriteLine(u));
        }
    }
}
5

Compare Semantic Versions — IComparable<SemVer>

IComparable<T>VersioningParsingModerate

Scenario: Your deployment system sorts build versions like: MAJOR.MINOR.PATCH (optional -label). You must implement semantic version ordering. What to implement: - SemVer.CompareTo(SemVer? other) Rules: - Compare Major, then Minor, then Patch (ascending) - Pre-release label: versions WITHOUT label are greater than WITH label (release > prerelease) - If both have labels: compare label ordinal-ignore-case ✅ Implement ONLY the TODO method.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console
using System.Collections.Generic;                                    // List

namespace ItTechGenie.M1.IComparable.Q5
{
    public class SemVer : IComparable<SemVer>
    {
        public int Major { get; }
        public int Minor { get; }
        public int Patch { get; }
        public string? Label { get; }                                 // e.g., alpha/beta/rc

        public SemVer(int major, int minor, int patch, string? label)
        {
            Major = major; Minor = minor; Patch = patch; Label = label;
        }

        // ✅ TODO: Student must implement only this method
        public int CompareTo(SemVer? other)
        {
            // TODO:
            // - handle null other
            // - compare Major, Minor, Patch
            // - release (Label null/empty) > prerelease (Label set)
            // - label compare if both have
            throw new NotImplementedException();
        }

        public override string ToString()
            => $"{Major}.{Minor}.{Patch}" + (string.IsNullOrWhiteSpace(Label) ? "" : "-" + Label);
    }

    internal class Program
    {
        static void Main()
        {
            var list = new List<SemVer>
            {
                new SemVer(1,2,10,null),
                new SemVer(1,2,2,null),
                new SemVer(1,2,2,"alpha ✅"),
                new SemVer(1,2,2,"beta"),
                new SemVer(2,0,0,null)
            };

            list.Sort();
            list.ForEach(v => Console.WriteLine(v));
        }
    }
}
6

Leaderboard Ranking — Compare by Score DESC then Name ASC

IComparable<T>SortingBusiness ruleModerate

Scenario: A game leaderboard must rank players: - Higher score should come first - If score equal: name ascending (ignore case) - If still equal: userId ascending ordinal What to implement: - PlayerRank.CompareTo(PlayerRank? other) ✅ Implement ONLY the TODO method.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console
using System.Collections.Generic;                                    // List

namespace ItTechGenie.M1.IComparable.Q6
{
    public class PlayerRank : IComparable<PlayerRank>
    {
        public string UserId { get; }
        public string Name { get; }
        public int Score { get; }

        public PlayerRank(string userId, string name, int score)
        {
            UserId = userId;
            Name = name;
            Score = score;
        }

        // ✅ TODO: Student must implement only this method
        public int CompareTo(PlayerRank? other)
        {
            // TODO:
            // - null handling
            // - Score DESC (invert compare)
            // - Name ASC ignore case
            // - UserId ASC ordinal
            throw new NotImplementedException();
        }

        public override string ToString() => $"{Score} | {Name} | {UserId}";
    }

    internal class Program
    {
        static void Main()
        {
            var list = new List<PlayerRank>
            {
                new PlayerRank("u-α12", "Sana ✅", 1200),
                new PlayerRank("u-β77", "ravi#1", 1200),
                new PlayerRank("u- 001 ", "Arjun α/β", 1500),
                new PlayerRank("u-zzz", "Sana ✅", 1200),
            };

            list.Sort();
            list.ForEach(x => Console.WriteLine(x));
        }
    }
}
7

Natural Sort for File Names — IComparable with Numeric Segments

IComparable<T>Natural sortParsingComplex

Scenario: A download center lists files: "lesson 2.txt" should come before "lesson 10.txt". Implement natural ordering based on numeric segments inside the name. What to implement: - FileEntry.CompareTo(FileEntry? other) Rules: - Split into alternating text and number tokens - Compare token-by-token: - text: case-insensitive - number: numeric compare - If one ends earlier: shorter token list first ✅ Implement ONLY the TODO method.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console
using System.Collections.Generic;                                    // List
using System.Text.RegularExpressions;                                // Regex

namespace ItTechGenie.M1.IComparable.Q7
{
    public class FileEntry : IComparable<FileEntry>
    {
        public string Name { get; }
        public FileEntry(string name) => Name = name;

        // ✅ TODO: Student must implement only this method
        public int CompareTo(FileEntry? other)
        {
            // TODO:
            // - handle null
            // - tokenize using regex for numbers
            // - compare tokens (text ignore-case, number numeric)
            // - fallback to ordinal when needed
            throw new NotImplementedException();
        }

        public override string ToString() => Name;
    }

    internal class Program
    {
        static void Main()
        {
            var list = new List<FileEntry>
            {
                new FileEntry("lesson 2 ✅.txt"),
                new FileEntry("lesson 10.txt"),
                new FileEntry("lesson 1.txt"),
                new FileEntry("Lesson 02.txt"),
                new FileEntry("lesson α.txt"),
            };

            list.Sort();
            list.ForEach(f => Console.WriteLine(f));
        }
    }
}
8

Top‑K Selector — Generic Heapless Selection using IComparable<T>

GenericsIComparable<T>Top-KPerformanceComplex

Scenario: You need top K highest values from a large list without sorting the entire list. Implement a simple top-K selection. What to implement: - TopK.SelectTopK<T>(IEnumerable<T> items, int k) -> List<T> Rules: - where T : IComparable<T> - Keep a list of size at most K - Insert item and remove smallest when size > K - Return result sorted descending ✅ Implement ONLY the TODO method.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console
using System.Collections.Generic;                                    // List, IEnumerable
using System.Linq;                                                  // LINQ

namespace ItTechGenie.M1.IComparable.Q8
{
    public static class TopK
    {
        // ✅ TODO: Student must implement only this method
        public static List<T> SelectTopK<T>(IEnumerable<T> items, int k) where T : IComparable<T>
        {
            // TODO:
            // - validate inputs and k > 0
            // - keep a list top
            // - for each item: add; if count > k remove smallest
            // - finally sort descending and return
            throw new NotImplementedException();
        }
    }

    internal class Program
    {
        static void Main()
        {
            var nums = new List<int> { 99, 100, 5, 100, 42, 7 };
            var top3 = TopK.SelectTopK(nums, 3);

            Console.WriteLine("Top 3:");
            top3.ForEach(Console.WriteLine);
        }
    }
}
9

Schedule Conflict Detector — Sort by Time using IComparable<Slot>

IComparable<T>SortingConflict detectionComplex

Scenario: A meeting scheduler must detect overlaps. First, sort slots by StartTime, then EndTime. What to implement: - Slot.CompareTo(Slot? other) - Scheduler.HasOverlap(List<Slot> slots) -> bool Rules: - CompareTo: Start ascending then End ascending then Title ordinal - HasOverlap: sort list, then check if slot[i].Start < slot[i-1].End ✅ Implement ONLY the TODO methods.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console, TimeSpan
using System.Collections.Generic;                                    // List

namespace ItTechGenie.M1.IComparable.Q9
{
    public class Slot : IComparable<Slot>
    {
        public TimeSpan Start { get; }
        public TimeSpan End { get; }
        public string Title { get; }

        public Slot(TimeSpan start, TimeSpan end, string title)
        {
            Start = start; End = end; Title = title;
        }

        // ✅ TODO: Student must implement only this method
        public int CompareTo(Slot? other)
        {
            // TODO:
            // - null handling
            // - compare Start then End then Title ordinal
            throw new NotImplementedException();
        }

        public override string ToString() => $"{Start}-{End} | {Title}";
    }

    public static class Scheduler
    {
        // ✅ TODO: Student must implement only this method
        public static bool HasOverlap(List<Slot> slots)
        {
            // TODO:
            // - validate input
            // - sort (uses Slot.CompareTo)
            // - scan and check overlap
            throw new NotImplementedException();
        }
    }

    internal class Program
    {
        static void Main()
        {
            var slots = new List<Slot>
            {
                new Slot(TimeSpan.Parse("10:00"), TimeSpan.Parse("10:30"), "Standup ✅"),
                new Slot(TimeSpan.Parse("10:20"), TimeSpan.Parse("11:00"), "Client call α/β"),
                new Slot(TimeSpan.Parse("11:00"), TimeSpan.Parse("11:15"), "Break"),
                new Slot(TimeSpan.Parse("11:10"), TimeSpan.Parse("11:30"), "Review!@#"),
            };

            Console.WriteLine("Overlap? " + Scheduler.HasOverlap(slots));
        }
    }
}
10

Deterministic Ordering for Audit Events — IComparable + SortedSet

IComparable<T>SortedSetDeterminismComplex

Scenario: A security system stores audit events in a SortedSet so duplicates are removed. But duplicates are determined by CompareTo returning 0. You need deterministic ordering and correct duplicate detection. What to implement: - AuditEvent.CompareTo(AuditEvent? other) Rules: - If CompareTo returns 0 => SortedSet treats them equal (one removed) - Decide uniqueness by EventId first (ordinal), then Timestamp, then Severity, then Message - Severity order: INFO < WARN < ERROR < CRITICAL - Ensure CompareTo never returns 0 for truly different EventId ✅ Implement ONLY the TODO method.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console
using System.Collections.Generic;                                    // SortedSet

namespace ItTechGenie.M1.IComparable.Q10
{
    public class AuditEvent : IComparable<AuditEvent>
    {
        public string EventId { get; }
        public TimeSpan Time { get; }
        public string Severity { get; }
        public string Message { get; }

        public AuditEvent(string eventId, TimeSpan time, string severity, string message)
        {
            EventId = eventId; Time = time; Severity = severity; Message = message;
        }

        private static int SevRank(string sev)                         // map severity to rank
        {
            // INFO < WARN < ERROR < CRITICAL (lowest first)
            return sev?.ToUpperInvariant() switch
            {
                "INFO" => 1,
                "WARN" => 2,
                "ERROR" => 3,
                "CRITICAL" => 4,
                _ => 99
            };
        }

        // ✅ TODO: Student must implement only this method
        public int CompareTo(AuditEvent? other)
        {
            // TODO:
            // - null handling
            // - EventId ordinal (Trim not required but allowed)
            // - then Time
            // - then severity rank
            // - then Message ordinal
            // - ensure different EventId cannot return 0
            throw new NotImplementedException();
        }

        public override string ToString() => $"{EventId} | {Time} | {Severity} | {Message}";
    }

    internal class Program
    {
        static void Main()
        {
            var set = new SortedSet<AuditEvent>();                     // uses CompareTo for ordering + uniqueness

            set.Add(new AuditEvent("EVT-α12", TimeSpan.Parse("10:05:02"), "WARN", "Login fail ✅"));
            set.Add(new AuditEvent("EVT-α12", TimeSpan.Parse("10:05:02"), "WARN", "Login fail ✅")); // duplicate
            set.Add(new AuditEvent("EVT-β77", TimeSpan.Parse("10:05:02"), "ERROR", "Timeout!@#"));
            set.Add(new AuditEvent("EVT- 001 ", TimeSpan.Parse("10:05:01"), "INFO", "View page /c#?x=αβ"));

            foreach (var e in set) Console.WriteLine(e);
        }
    }
}
11

Order Processing Rules — Fallback to IComparable and Custom Tie‑Breaker

IComparable<T>Custom comparerBusiness orderingComplex

Scenario: Order processing pipeline must sort orders for picking: - Urgent orders first - Then earliest delivery date - Then higher total amount first - If still tie: orderNumber ascending Your domain type implements IComparable<Order> for default sort. But for one screen, you need an alternate tie-breaker: by CustomerName. What to implement: - Order.CompareTo(Order? other) (default sorting) - OrderComparers.ByCustomerNameThenDefault() -> IComparer<Order> Rules: - CompareTo implements default rule (Urgent DESC, DeliveryDate ASC, Amount DESC, OrderNo ASC) - Custom comparer sorts CustomerName ASC (ignore case) then falls back to CompareTo for rest - Use Comparer<Order>.Create(...) or implement IComparer<Order> ✅ Implement ONLY the TODO methods.

✅ Sample input includes spaces, quotes, unicode α/β, emoji ✅, and special chars to test parsing and comparison edge cases.
IComparable / Sorting scenario (students implement ONLY TODO methods) Ctrl+C
using System;                                                     // Console, DateTime
using System.Collections.Generic;                                    // IComparer, List

namespace ItTechGenie.M1.IComparable.Q11
{
    public class Order : IComparable<Order>
    {
        public string OrderNo { get; }
        public bool Urgent { get; }
        public DateTime DeliveryDate { get; }
        public decimal Amount { get; }
        public string CustomerName { get; }

        public Order(string orderNo, bool urgent, DateTime deliveryDate, decimal amount, string customerName)
        {
            OrderNo = orderNo; Urgent = urgent; DeliveryDate = deliveryDate; Amount = amount; CustomerName = customerName;
        }

        // ✅ TODO: Student must implement only this method
        public int CompareTo(Order? other)
        {
            // TODO:
            // - null handling
            // - Urgent DESC (true first)
            // - DeliveryDate ASC
            // - Amount DESC
            // - OrderNo ASC ordinal
            throw new NotImplementedException();
        }

        public override string ToString() => $"{(Urgent ? "URGENT" : "normal")} | {DeliveryDate:yyyy-MM-dd} | ₹{Amount} | {OrderNo} | {CustomerName}";
    }

    public static class OrderComparers
    {
        // ✅ TODO: Student must implement only this method
        public static IComparer<Order> ByCustomerNameThenDefault()
        {
            // TODO:
            // - compare CustomerName ignore-case
            // - if equal, fallback to x.CompareTo(y)
            throw new NotImplementedException();
        }
    }

    internal class Program
    {
        static void Main()
        {
            var list = new List<Order>
            {
                new Order("O- 90 01 ✅", true,  DateTime.Parse("2026-02-18"), 1999.25m, "Sana Suresh"),
                new Order("O-β77",      false, DateTime.Parse("2026-02-18"), 7999m,     "ravi#1"),
                new Order("O-α12",      true,  DateTime.Parse("2026-02-17"), 1299.50m,  "Arjun α/β"),
            };

            Console.WriteLine("Default sort (CompareTo):");
            list.Sort();                                             // uses CompareTo
            list.ForEach(o => Console.WriteLine(o));

            Console.WriteLine("\nCustom screen sort (CustomerName, then default):");
            list.Sort(OrderComparers.ByCustomerNameThenDefault());    // custom comparer
            list.ForEach(o => Console.WriteLine(o));
        }
    }
}