using System.Collections.Generic;
using System.Runtime.CompilerServices;
public interface INotification
Severity Severity { get; set; }
string Message { get; set; }
static string MakeDefaultSeverityName<TNotification>(TNotification notification) where TNotification : INotification => notification?.Severity.ToString().ToLower();
public string SeverityName => MakeDefaultSeverityName(this);
public class Notification : INotification
public Severity Severity { get; set; }
public string Message { get; set; }
public class NotificationWithOverride : Notification
public string SeverityName => INotification.MakeDefaultSeverityName(this);
static void Main(string[] args)
ShowPropertiesAndMethods<INotification>();
Test<NotificationWithOverride>();
static void Test<TNotification>() where TNotification : INotification, new()
Console.WriteLine("\nTesting {0}:", typeof(TNotification));
var notification = new TNotification
ShowPropertiesAndMethods<TNotification>();
ShowInterfaceMapping(typeof(INotification), typeof(TNotification));
Console.WriteLine("{0} = {1}", nameof(INotification.SeverityName), notification.SeverityName);
var jsonText = JsonSerializer.Serialize(notification);
Console.WriteLine("Serialization result from System.Text.Json:");
Console.WriteLine(jsonText);
Console.WriteLine("Serialization result from Json.NET:");
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(notification));
private static void ShowPropertiesAndMethods<TNotification>()
Console.WriteLine("Properties of {0}: {1}", typeof(TNotification).Name, string.Join(", ", typeof(TNotification).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Select(p => p.Name)));
Console.WriteLine("Methods of {0}: {1}", typeof(TNotification).Name, string.Join(", ", typeof(TNotification).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Select(p => p.Name)));
private static void ShowInterfaceMapping(Type intType, Type implType)
InterfaceMapping map = implType.GetInterfaceMap(intType);
Console.WriteLine("Mapping of {0} to {1}: ", map.InterfaceType, map.TargetType);
for (int ctr = 0; ctr < map.InterfaceMethods.Length; ctr++) {
MethodInfo im = map.InterfaceMethods[ctr];
MethodInfo tm = map.TargetMethods[ctr];
Console.WriteLine(" {0} --> {1} (Reflected type {2})", im.Name,tm.Name, tm.ReflectedType);