Let's suppose you have these two classes:
public class ClassA
{
public int Id { get; set; }
public string Description { get; set; }
public DateTime CreatedAt { get; set; }
}
public class ClassB
{
public string Id { get; set; }
public string Description { get; set; }
public string CreatedBy { get; set; }
}
To retrieve only those properties that are defined in that class (and not inherited):
public static Dictionary<string, PropertyInfo> GetProperties<TClass>() where TClass : class
{
return typeof(TClass)
.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.ToDictionary(prop => prop.Name);
}
To spot the missing ones:
public static IEnumerable<string> GetMissingProperties(string lhsName, IList<string> lhsPropertyNames, string rhsName, IList<string> rhsPropertyNames)
{
var lhsMissingOnes = lhsPropertyNames.Except(rhsPropertyNames).Select(prop => lhsName + " defines " + prop + " but " + rhsName + " does not.");
var rhsMissingOnes = rhsPropertyNames.Except(lhsPropertyNames).Select(prop => rhsName + " defines " + prop + " but " + lhsName + " does not.");
return lhsMissingOnes.Union(rhsMissingOnes);
}
To spot the ones with different types:
public static IEnumerable<string> GetDifferentlyTypedProperties(string lhsName, Dictionary<string, PropertyInfo> lhsProperties, string rhsName, Dictionary<string, PropertyInfo> rhsProperties)
{
var differentTypes = new List<string>();
var definedInBoth = lhsProperties.Keys.Intersect(rhsProperties.Keys);
foreach (var prop in definedInBoth)
{
var lhsType = lhsProperties[prop].PropertyType;
var rhsType = rhsProperties[prop].PropertyType;
if (lhsType != rhsType)
{
var message = prop + " has a type '" + lhsType + "' in " + lhsName + " and '" + rhsType + "' type in " + rhsName;
differentTypes.Add(message);
}
}
return differentTypes;
}
Putting everything all together:
public static void Main()
{
var propertiesOfA = GetProperties<ClassA>();
var propertiesOfB = GetProperties<ClassB>();
var missingProperties = GetMissingProperties(nameof(ClassA), propertiesOfA.Keys.ToList(), nameof(ClassB), propertiesOfB.Keys.ToList());
foreach (var message in missingProperties) Console.WriteLine(message);
var differentProperties = GetDifferentlyTypedProperties(nameof(ClassA), propertiesOfA, nameof(ClassB), propertiesOfB);
foreach (var message in differentProperties) Console.WriteLine(message);
}
The output will be:
ClassA defines CreatedAt but ClassB does not.
ClassB defines CreatedBy but ClassA does not.
Id has a type 'System.Int32' in ClassA and 'System.String' type in ClassB