mardi 30 juin 2020

Get all properties of an object using reflection - but only the properties where the object has a value for them (not default value or null)

So I'm wanting to return the properties of an object, either generic or hard coded typeof(User) for e.g

However i only want to return the properties where the object I'm getting the properties for, has a value set against it, not the default value nor null. The reason for this is so that i can use these properties only to build an expression to only check these properties against columns in our database for items.

I tried something like this, however it still brings back all the values,

public User AutomatedUser {get;set;} // some properties of this will populated elsewhere

var props = typeof(User).GetProperties()
            .Where(pi => pi.GetValue(AutomatedFromUser) != pi.PropertyType.GetDefault());

I then found this method on the forum for getting default values of types, as compiler won't allow != default(pi.PropertyType) as "Pi" is a variable. Method below...

public static object GetDefault(this Type type)
    {
        // If no Type was supplied, if the Type was a reference type, or if the Type was a System.Void, return null
        if (type == null || !type.IsValueType || type == typeof(void))
            return null;

        // If the supplied Type has generic parameters, its default value cannot be determined
        if (type.ContainsGenericParameters)
            throw new ArgumentException(
                "{" + MethodInfo.GetCurrentMethod() + "} Error:\n\nThe supplied value type <" + type +
                "> contains generic parameters, so the default value cannot be retrieved");

        // If the Type is a primitive type, or if it is another publicly-visible value type (i.e. struct), return a 
        //  default instance of the value type
        if (type.IsPrimitive || !type.IsNotPublic)
        {
            try
            {
                return Activator.CreateInstance(type);
            }
            catch (Exception e)
            {
                throw new ArgumentException(
                    "{" + MethodInfo.GetCurrentMethod() + "} Error:\n\nThe Activator.CreateInstance method could not " +
                    "create a default instance of the supplied value type <" + type +
                    "> (Inner Exception message: \"" + e.Message + "\")", e);
            }
        }

        // Fail with exception
        throw new ArgumentException("{" + MethodInfo.GetCurrentMethod() + "} Error:\n\nThe supplied value type <" + type +
                                    "> is not a publicly-visible type, so the default value cannot be retrieved");
    }
}

Any tips or help would be greatly appreciated as to why this wouldn't be working, or where i'm going wrong.





Aucun commentaire:

Enregistrer un commentaire