using System.Collections.Generic;
public class NullValueDictionary<T, U> : Dictionary<T, U> where U : class
new public U? this[T key] {
this.TryGetValue(key, out var val);
public abstract class Shadow {
protected abstract Type ModelType { get; }
public String Type() => ModelType.Name;
public dynamic Root() => Convert.ChangeType(this, ModelType);
public T To<T>() => (T) Convert.ChangeType(this, typeof(T));
public bool Is(Type type) => type == ModelType;
public bool Has(String prop) => this.GetType().GetProperty(prop) != null;
public NullValueDictionary<Type, dynamic> In(Type[] list) {
var results = new NullValueDictionary<Type, dynamic>();
var item = list.Where(x => Is(x)).Single();
var instance = Activator.CreateInstance(item);
results.Add(item, instance);
public class Type1 : Shadow {
sealed protected override Type ModelType { get; } = typeof(Type1);
public string Prefix { get; } = "1";
public string? Name { get; init; }
public class Type2 : Shadow {
sealed protected override Type ModelType { get; } = typeof(Type2);
public string Prefix { get; } = "2";
public string? Name { get; init; }
public string? Suffix { get; init; }
public static void Main() {
var t1 = new Type1 { Name = "Name1" };
var t2 = new Type2 { Name = "Name2", Suffix = "Ext" };
Shadow[] shadows = new [] { (t1 as Shadow), (t2 as Shadow) };
List<dynamic> roots = shadows.Select(m => m.Root()).ToList();
var types = shadows.Select(m => m.Type());
var names = roots.Select(m => m.Name);
dynamic t1Root = roots[0], t2Root = roots[1];
Console.WriteLine(types.Aggregate((i, j) => i + "," + j));
Console.WriteLine(names.Aggregate((i, j) => i + "," + j));
@file {t1Root.Prefix}_{t1Root.Name}_{(t1Root.Has("Suffix") ? t1Root.Suffix + "_" : "")}Info.log
@brief This file contains general information.
Warning! This is a generated file. Manual changes will be omitted.
@file {t2Root.Prefix}_{t2Root.Name}_{(t2Root.Has("Suffix") ? t2Root.Suffix + "_" : "")}Info.log
@brief This file contains general information.
Warning! This is a generated file. Manual changes will be omitted.
Type type1 = typeof(Type1), type2 = typeof(Type2);
t1OM = model1.To<Type1>();
} catch (InvalidCastException) {
var nvdModelSet = model2.In(new [] { type1, type2 });
if (!nvdModelSet.Values.Any(x => x != null))
Type2? t2OM = nvdModelSet[type2];
@file {t1OM.Prefix}_{t1OM.Name}_Info.log
@brief This file contains general information.
Warning! This is a generated file. Manual changes will be omitted.
@file {t2OM.Prefix}_{t2OM.Name}_{t2OM.Suffix}_Info.log
@brief This file contains general information.
Warning! This is a generated file. Manual changes will be omitted.
if (model2.Is(type2) && t2OM != null) {
@file {t2OM.Prefix}_{t2OM.Name}_{t2OM.Suffix}_Info.log
@brief This file contains general information.
Warning! This is a generated file. Manual changes will be omitted.