gpt4 book ai didi

c# - 如何高效地使用 GetProperties()?

转载 作者:太空狗 更新时间:2023-10-30 01:32:51 29 4
gpt4 key购买 nike

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

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

最佳答案

通过 memoizing它的结果。将结果保存在 Dictionary<Type, PropertyInfo[]> 中,然后在函数的开头检查您是否已经计算过它。如果是,返回 Dictionary<,> 的值.如果你想让它线程安全,使用 ConcurrentDictionary<Type, PropertyInfo[]> .

类似于:

//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 的类型在编译时,它可以通过另一种方式进行优化,通过在静态泛型类的字段中进行内存:

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 树)一些代码来清理对象。它变得更快,但代码生成变得更慢。而且执行此操作的代码要复杂得多。

关于c# - 如何高效地使用 GetProperties()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35941598/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com