C# Programming Labs

Go deeper with generics and constraints, advanced LINQ (GroupBy/Join), and JSON serialization using System.Text.Json.

Generics, LINQ Advanced & JSON - Module 6

Master reusable types, powerful queries, and modern data formats.

Lab 16: Generics & Constraints
Expert
Coding Challenge
Your Task: Create a generic class and a generic method with constraints, then use them with different type arguments.

Detailed Requirements:
1. Create a generic class Box<T> with a read-only property and method: class Box<T> { public T Value { get; private set; } public Box(T value) { Value = value; } public void SetValue(T value) { Value = value; } public void Describe() => Console.WriteLine($"T is {typeof(T).Name}"); }
2. Create a generic method with a constraint: static class Utils { public static T Max<T>(T a, T b) where T : IComparable<T> { return a.CompareTo(b) >= 0 ? a : b; } }
3. Use your types: Instantiate Box<int> and Box<string>, print their values, call Describe(), and use Utils.Max for ints and strings.

💡 Pro Tips:
• Prefer generics over object casting for type safety and performance
• Use constraints (where) to express capabilities required (class, struct, interfaces, parameterless ctor)
• Avoid boxing/unboxing by using value-type generics directly
• Generic methods can live in non-generic classes, too

Expected Output: Box<int> value: 42 Box<string> value: hello T is Int32 Max int: 10 Max string: orange

Requirements Checklist

Define generic class Box<T> with a property
Implement generic method Max<T> with IComparable constraint
Instantiate Box<int> and Box<string>
Print Box values and call Describe()
Use Utils.Max for ints and strings
Code compiles and prints expected lines
Output
// Click "Run Code" to compile and execute
Hints & Tips
• Generic class: class Box<T> { T Value { get; } }
• Constraint: where T : IComparable<T>
• Instantiate: new Box<int>(42), new Box<string>("hi")
• typeof(T).Name shows the type argument at runtime
Progress: 0/6
Score: 0/100
0%

Lab Results

Review feedback below

Lab 17: LINQ Advanced (GroupBy & Join)
Expert
Coding Challenge
Your Task: Use LINQ to group items and join related collections to produce aggregated, ordered results.

Detailed Requirements:
1. Create data models and lists: class Student { public int Id; public string Name; public int DeptId; } class Department { public int Id; public string Name; } Make List<Student> and List<Department> with sample data.

2. Group students by department (GroupBy): Produce counts per department.
3. Join/group-join with departments: Show department names with counts and order by count descending.
4. Join students to departments: Show each student's name and department using Join, ordered by student name.
5. Use projections: Select into anonymous types.
6. Materialize results: Use ToList() or ToDictionary() where appropriate.

💡 Pro Tips:
• Remember using System.Linq;
• GroupJoin can compute aggregates from related items
• LINQ is deferred until enumerated; call ToList() to execute immediately

Expected Output: Students per department: Engineering: 3 Marketing: 2 Join sample: Alice -> Engineering Bob -> Engineering Chloe -> Marketing David -> Engineering Eve -> Marketing

Requirements Checklist

Create List<Student> and List<Department>
Use GroupBy for counts per department
Use Join or GroupJoin with Department
Order results by count or name
Project with Select into anonymous types
Materialize with ToList/ToDictionary
Output
// Click "Run Code" to compile and execute
Hints & Tips
• Remember using System.Linq;
• Group + join: students.GroupBy(s => s.DeptId).Join(depts, g => g.Key, d => d.Id, ...)
• Materialize: .ToList() to execute queries
• Query syntax also works: from s in students join d in depts on s.DeptId equals d.Id select ...
Progress: 0/6
Score: 0/100
0%

Lab Results

Review feedback below

Lab 18: JSON with System.Text.Json
Expert
Coding Challenge
Your Task: Serialize and deserialize objects using System.Text.Json with options.

Detailed Requirements:
1. Create a POCO: class Person { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } } 2. Serialize with options: Use JsonSerializerOptions { WriteIndented = true }.
3. Deserialize back to object: From the JSON string to Person.
4. Print both: Pretty JSON, then the deserialized object's properties.
5. Optional: Add [JsonPropertyName("...")] annotations (requires System.Text.Json.Serialization).

💡 Pro Tips:
• Avoid trailing commas in JSON
• Options like PropertyNameCaseInsensitive help with casing mismatches
• Prefer System.Text.Json in modern .NET for performance

Expected Output: Serialized JSON: { "Name": "Alice", "Age": 25, "Email": "alice@example.com" } Deserialized: Alice (25) - alice@example.com

Requirements Checklist

Define Person class with Name, Age, Email
Serialize with JsonSerializer and WriteIndented
Deserialize JSON back to Person
Print serialized JSON and deserialized fields
Use System.Text.Json namespaces
Code compiles and runs
Output
// Click "Run Code" to compile and execute
Hints & Tips
• Namespaces: using System.Text.Json; (+ ...Serialization if using attributes)
• Options: new JsonSerializerOptions { WriteIndented = true }
• Serialize: JsonSerializer.Serialize(obj, options)
• Deserialize: JsonSerializer.Deserialize<Type>(json)
Progress: 0/6
Score: 0/100
0%

Lab Results

Review feedback below