Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I ignore all hidden properties of class being inherited using reflection?

Im having an issue where I need to get all properties from an object, then sort through the properties and send the values of certain properties to another service. Here is an example of the code:

public class Class1
{
    public string A { get; set; }
    public bool B  { get; set; }
}

public class Class2 : Class1 
{
    public new bool? B { get; set; }
    public bool C { get; set; }
}

I need to get all the properties of Class2, however when using Class2.GetType().GetProperties(), the result contains B from Class2 AND Class1. This causes my issue as when looping through each property I am sending B twice, one with the default value of false since it was never set, then the other with the proper value that was set by my service. I need the result to contain B from Class2, A from Class1, and C from Class2 but ignore B from Class1 since it has been hidden with the new keyword.

I have tried looking through the binding flags I can use, but it has not helped. The closest flag I can find is the BindingFlags.DeclaredOnly flag, but that excludes A from Class1, so it will not work for me.

How would I go about ignoring the original property if it has been hidden?

like image 581
blueberrywaffle Avatar asked Oct 29 '25 07:10

blueberrywaffle


2 Answers

You could use a LINQ query to filter out the hidden properties.

var allProps = typeof(Class2).GetProperties(
        BindingFlags.Instance | BindingFlags.Public
);

var thePropsYouWant = 
        from p in allProps
        group p by p.Name into g
        select g.OrderByDescending(t => t.DeclaringType == typeof(Class2)).First();

See it running here: https://dotnetfiddle.net/V5sGIs

like image 125
Blorgbeard Avatar answered Oct 30 '25 23:10

Blorgbeard


If I understand you right you need all properties from Class2 and all properties from Class1 that not redefined in Class2

You can achive this with two calls to GetProperties: first select all defined in Class2 then visit type of Class1 and add any that missing

var type = typeof(Class2);
var list = new List<PropertyInfo>();
list.AddRange(type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly));

var baseType = type.BaseType;
if (baseType != null)
{
    foreach (var propertyInfo in baseType.GetProperties())
    {
        if (list.All(p => p.Name != propertyInfo.Name))
            list.Add(propertyInfo);
    }
}

If you print that list

foreach (var propertyInfo in list)
    Console.WriteLine($"From {propertyInfo.DeclaringType} > '{propertyInfo.Name}':{propertyInfo.PropertyType}");

You will see something like:

From Class2 > 'B':System.Nullable`1[System.Boolean]
From Class1 > 'A':System.String

like image 28
Aleks Andreev Avatar answered Oct 30 '25 23:10

Aleks Andreev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!