C# 如何有效地使用GetProperties()?

C# 如何有效地使用GetProperties()?,c#,C#,我经常使用这种方法。我如何优化它?因为我知道value.GetType().GetProperties()以递归方式工作(对于基本对象,然后是基本对象属性,然后是基本对象属性的每个属性,等等)。将结果保存在字典中,然后在函数开始时检查您是否已经计算过它。如果是,则返回字典的值。如果要使其线程安全,请使用ConcurrentDictionary 比如: public object GetObjectToSerialize(object value, Type targetType) {

我经常使用这种方法。我如何优化它?因为我知道
value.GetType().GetProperties()以递归方式工作(对于基本对象,然后是基本对象属性,然后是基本对象属性的每个属性,等等)

。将结果保存在
字典中
,然后在函数开始时检查您是否已经计算过它。如果是,则返回
字典的值。如果要使其线程安全,请使用
ConcurrentDictionary

比如:

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;
 }
如果您有以下情况,则代码的第二个版本将不起作用:

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);
只有在您具备以下条件的情况下,它才会起作用:

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);

另一种可能的解决方案是(通过
表达式
树)在运行时生成一些代码来清理对象。它变得快得多,但代码生成变得慢得多。执行此操作的代码要复杂得多。

为什么不添加序列化程序属性?为什么我需要添加它?您知道您正在将
foreach
中的
密码属性的值设置为
null
,对吗?@xanatos是的,谢谢