Skip to content

Instantly share code, notes, and snippets.

@solarshado
Created March 16, 2017 19:19
Show Gist options
  • Save solarshado/1a32b7b24501fd22ca4c5969d88dc620 to your computer and use it in GitHub Desktop.
Save solarshado/1a32b7b24501fd22ca4c5969d88dc620 to your computer and use it in GitHub Desktop.
some C# using reflection and LINQ to find common properties and generate corresponding interfaces
public void Whatever()
{
var itemTypes = typeof(IItemBase).Assembly.GetTypes()
.Where(t => t.IsClass && typeof(IItemBase).IsAssignableFrom(t))
.ToArray();
var propertyMap = itemTypes.ToDictionary(t => t, t => t.GetProperties().Select(p => new { p.Name, p.PropertyType }).OrderBy(p => p.Name).ToArray());
var distinctNames = propertyMap.Values.SelectMany(_ => _).Select(p => p.Name).Distinct();
var props = propertyMap.Values.SelectMany(_ => _).GroupBy(p => p.Name);
var wut = props.Where(g => g.Any(p => p.PropertyType != g.First().PropertyType)).ToArray();
var wat = wut.Select(w => w.Key).ToArray();
var propTypeMap = props.ToDictionary(pg => pg.Key, pg => pg.First().PropertyType);
var namesByCommonness = distinctNames.ToDictionary(
n => n,
n =>
{
var tmp = propertyMap.Where(kvp => kvp.Value.Any(p => p.Name.Equals(n)));
var tmp2 = new { count = tmp.Count(), types = new HashSet<Type>(tmp.Select(_ => _.Key)) };
return tmp2;
});
var singlesExcluded = namesByCommonness
.Where(kvp => kvp.Value.count > 1)
.Select(kvp => new { prop = kvp.Key, kvp.Value.types })
.ToArray();
var grouped = singlesExcluded.GroupBy(p => p.types, HashSet<Type>.CreateSetComparer());
var ifaces = grouped
.Select(g => new { implementors = g.Key.ToArray(), members = g.Select(p => p.prop).ToArray() })
//.OrderByDescending(i => i.implementors.Length).ThenByDescending(i => i.members.Length)
.OrderByDescending(i => i.implementors.Length + i.members.Length)
.Select((iface, idx) => new { iface.implementors, iface.members, name = "IItemGenerated" + idx })
.ToArray();
var whereWat = ifaces.Where(i => wat.Any(w => i.members.Contains(w))).ToArray();
const string ifFmt = "public interface {0} {{\n{1}\n}}",
ifMemebrFmt = "\t{1} {0} {{get;set;}}",
classFmt = "public partial class {0} : {1} {{}}";
var ifaceDefs = string.Join("\n\n", ifaces.Select(i => string.Format(ifFmt, i.name, string.Join("\n", i.members.Select(m => string.Format(ifMemebrFmt, m, propTypeMap[m].Name)).ToArray()))));
var classDefs = string.Join("\n\n", itemTypes.Select(t => string.Format(classFmt, t.Name, string.Join(", ", ifaces.Where(i => i.implementors.Contains(t)).Select(i => i.name)))));
var xmlifaces = new XDocument(new XElement("interfaces",
ifaces.Select(iface => new XElement("interface",
new XAttribute("name", iface.name),
new XAttribute("members", iface.members.Length),
new XAttribute("implementors", iface.implementors.Length),
new XElement("members", iface.members.Select(m => new XElement("member", m))),
new XElement("implementors", iface.implementors.Select(impl => new XElement("implementor", impl.Name))),
new XElement("exceptions", itemTypes.Except(iface.implementors).Select(ex => new XElement("exception", ex.Name)))
))
));
var str = xmlifaces.ToString();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment