Warm‑up: Reflection Toolkit (Inspect + Attribute + Invoke) — with hidden reference answer
Warm‑up (with answer): Implement a tiny reflection helper that demonstrates the key reflection options. This warm-up covers: - typeof(T) vs obj.GetType() - Listing public properties and methods (GetProperties / GetMethods) - Reading custom attributes (GetCustomAttributes) - Finding a method by name and invoking it (GetMethod + Invoke) - Safe binding flags (Public/Instance) and null checks ✅ Warm-up includes a reference answer (hidden behind a button).
using System; // Console
using System.Linq; // LINQ for filtering
using System.Reflection; // Reflection types
namespace ItTechGenie.M1.Reflection.WarmUp
{
[AttributeUsage(AttributeTargets.Property)] // attribute applies to properties
public sealed class MaskAttribute : Attribute // custom attribute class
{
public int VisibleChars { get; } // how many chars visible
public MaskAttribute(int visibleChars) => VisibleChars = visibleChars; // ctor
}
public class CustomerProfile // sample class to inspect
{
public string FullName { get; set; } = "Sana Suresh ✅"; // property 1
[Mask(2)]
public string Phone { get; set; } = "98 76 54 32 10"; // property 2 (masked)
public int LoyaltyPoints { get; set; } = 1200; // property 3
public string FormatDisplay(string prefix, string suffix) // method to invoke
=> $"{prefix} {FullName} ({LoyaltyPoints}) {suffix}"; // formatted output
}
public static class ReflectionWarmup
{
// ✅ Warm-up TODO: Student implements this helper
public static void PrintTypeSummary(Type t) // print properties + methods
{
// TODO:
// - print FullName of type
// - list public instance properties (name + type)
// - list public instance methods (exclude inherited from object if possible)
throw new NotImplementedException();
}
// ✅ Warm-up TODO: Student implements this helper
public static object? InvokeByName(object target, string methodName, params object?[] args)
{
// TODO:
// - null checks
// - find public instance method by name
// - invoke method with args
// - return result
throw new NotImplementedException();
}
// ✅ Warm-up TODO: Student implements this helper
public static int? ReadMaskVisibleChars(PropertyInfo p)
{
// TODO:
// - read MaskAttribute from property (if any)
// - return VisibleChars or null
throw new NotImplementedException();
}
}
internal class Program
{
static void Main()
{
var obj = new CustomerProfile(); // create instance
Type t1 = obj.GetType(); // runtime type
ReflectionWarmup.PrintTypeSummary(t1); // inspect
var phoneProp = t1.GetProperty(nameof(CustomerProfile.Phone)); // property info
Console.WriteLine("Mask VisibleChars=" +
(phoneProp == null ? "n/a" : ReflectionWarmup.ReadMaskVisibleChars(phoneProp)));
var result = ReflectionWarmup.InvokeByName(obj, "FormatDisplay", "Mr. α/β", "!@# ✅"); // invoke
Console.WriteLine("Invoke Result=" + result);
}
}
}
Warm‑up Reference Answer (Conceptual Steps)
Reference approach (key steps): 1) Listing properties: - Use t.GetProperties(BindingFlags.Public | BindingFlags.Instance) - Print p.Name and p.PropertyType.Name 2) Listing methods: - Use t.GetMethods(BindingFlags.Public | BindingFlags.Instance) - Optionally filter out methods where m.DeclaringType == typeof(object) 3) Reading attributes: - var attr = p.GetCustomAttributes(typeof(MaskAttribute), inherit:true).FirstOrDefault() as MaskAttribute; - Return attr?.VisibleChars 4) Invoking method: - var m = target.GetType().GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance); - return m?.Invoke(target, args); Always do null checks for PropertyInfo/MethodInfo.