How to work effectively with GetProperties ()?

public object GetObjectToSerialize(object value, Type targetType)
{
      var allProperties = value.GetType().GetProperties();

      var passwordProperties = allProperties.Where(p => p.PropertyType == typeof(string))
                                            .Where(p => p.Name.Contains("Password"))
                                            .ToList();

      var passwordWithoutEncryptedAttribute = passwordProperties
                .Where(p => !p.GetCustomAttributes(typeof(EncryptedConfigurationItemAttribute), false).Any());

       if (passwordWithoutEncryptedAttribute.Any())
       {
            throw new InvalidOperationException(SafeFormatter.Format(BackgroundJobsLocalization.Culture, BackgroundJobsLocalization.PasswordWithoutEncryptedAttribute));
       }

       foreach (var property in passwordProperties)
       {
            property.SetValue(value, null, null);
       }

        return value;
 }

I use this method quite often. How can I optimize it? Since, as I knew, it value.GetType().GetProperties();works recursively (for the base object, then for the properties of the base object, then each property of the properties of the base object, etc.)

+4
source share
1 answer

memoizing its result. Save the result to Dictionary<Type, PropertyInfo[]>, and then at the beginning of the function check that you have already calculated it. If yes, return the value Dictionary<,>. If you want to make it thread safe, use ConcurrentDictionary<Type, PropertyInfo[]>.

Sort of:

//private static readonly Dictionary<Type, PropertyInfo[]> PasswordProperties = new Dictionary<Type, PropertyInfo[]>();
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> PasswordProperties = new ConcurrentDictionary<Type, PropertyInfo[]>();

public static object GetObjectToSerialize(object value, Type targetType) {
    Type type = value.GetType();

    PropertyInfo[] properties;

    if (!PasswordProperties.TryGetValue(type, out properties)) 
    {
        properties = type.GetProperties()
                         .Where(p => p.PropertyType == typeof(string))
                         .Where(p => p.Name.Contains("Password"))
                         .ToArray();

        var passwordWithoutEncryptedAttribute = properties
                    .Where(p => !p.GetCustomAttributes(typeof(EncryptedConfigurationItemAttribute), false).Any());

        if (passwordWithoutEncryptedAttribute.Any()) {
            throw new InvalidOperationException(); // SafeFormatter.Format(BackgroundJobsLocalization.Culture, BackgroundJobsLocalization.PasswordWithoutEncryptedAttribute));
        }

        PasswordProperties[type] = properties;
    }

    foreach (var property in properties) 
    {
        property.SetValue(value, null, null);
    }

    return value;
}

value , -, memoizing :

public static class ObjectHelper
{
    public static T GetObjectToSerialize<T>(T value) 
    {
        foreach (var property in ObjectHelperInner<T>.Properties) 
        {
            property.SetValue(value, null, null);
        }

        return value;
    }

    private static class ObjectHelperInner<T>
    {
        public static readonly PropertyInfo[] Properties;

        static ObjectHelperInner()
        {
            PropertyInfo[] properties = typeof(T).GetProperties()
                                                    .Where(p => p.PropertyType == typeof(string))
                                                    .Where(p => p.Name.Contains("Password"))
                                                    .ToArray();

            var passwordWithoutEncryptedAttribute = properties
                        .Where(p => !p.GetCustomAttributes(typeof(EncryptedConfigurationItemAttribute), false).Any());

            if (passwordWithoutEncryptedAttribute.Any()) {
                throw new InvalidOperationException(); // SafeFormatter.Format(BackgroundJobsLocalization.Culture, BackgroundJobsLocalization.PasswordWithoutEncryptedAttribute));
            }

            Properties = properties;
        }
    }
}

, :

object obj = something;
ObjectHelper.GetObjectToSerialize(obj);

, :

SomeConcreteType obj = something;
ObjectHelper.GetObjectToSerialize(obj);

( Expression) . , . .

+3

All Articles