如何忽略使用反射继承的 class 的所有隐藏属性?
How do I ignore all hidden properties of class being inherited using reflection?
我遇到了一个问题,我需要从对象中获取所有属性,然后对属性进行排序并将某些属性的值发送到另一个服务。这是代码示例:
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; }
}
我需要获取 Class2 的所有属性,但是在使用 Class2.GetType().GetProperties() 时,结果包含来自 Class2 和 Class1 的 B。这导致了我的问题,因为当遍历每个 属性 时,我发送 B 两次,一次使用默认值 false 因为它从未设置过,然后另一个使用我的服务设置的正确值。我需要结果包含 Class2 中的 B、Class1 中的 A 和 Class2 中的 C,但忽略 Class1 中的 B,因为它已被 new 关键字隐藏。
我已经尝试查看我可以使用的绑定标志,但没有帮助。我能找到的最接近的标志是 BindingFlags.DeclaredOnly 标志,但是它从 Class1 中排除了 A,所以它对我不起作用。
如果原始 属性 已被隐藏,我将如何忽略它?
您可以使用 LINQ 查询来过滤掉隐藏的属性。
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();
在此处查看 运行:https://dotnetfiddle.net/V5sGIs
如果我理解你是对的,你需要 Class2
中的所有属性以及 Class1
中未在 Class2
中重新定义的所有属性
您可以通过两次调用 GetProperties
来实现此目的:首先 select 全部在 Class2
中定义,然后访问 Class1
的类型并添加任何缺失的 [=19] =]
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);
}
}
如果您打印该列表
foreach (var propertyInfo in list)
Console.WriteLine($"From {propertyInfo.DeclaringType} > '{propertyInfo.Name}':{propertyInfo.PropertyType}");
您会看到如下内容:
From Class2 > 'B':System.Nullable`1[System.Boolean]
From Class1 > 'A':System.String
一个简单的基于 LINQ 的解决方案,它以通用的方式适用于所有 class 层次结构:
var propertiesWithoutHiddenOnes = GetProperties(objectToUpdate.GetType())
.GroupBy(prop => prop.Name)
.Select(group => group.Aggregate(
(mostSpecificProp, other) => mostSpecificProp.DeclaringType.IsSubclassOf(other.DeclaringType) ? mostSpecificProp : other))
我遇到了一个问题,我需要从对象中获取所有属性,然后对属性进行排序并将某些属性的值发送到另一个服务。这是代码示例:
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; }
}
我需要获取 Class2 的所有属性,但是在使用 Class2.GetType().GetProperties() 时,结果包含来自 Class2 和 Class1 的 B。这导致了我的问题,因为当遍历每个 属性 时,我发送 B 两次,一次使用默认值 false 因为它从未设置过,然后另一个使用我的服务设置的正确值。我需要结果包含 Class2 中的 B、Class1 中的 A 和 Class2 中的 C,但忽略 Class1 中的 B,因为它已被 new 关键字隐藏。
我已经尝试查看我可以使用的绑定标志,但没有帮助。我能找到的最接近的标志是 BindingFlags.DeclaredOnly 标志,但是它从 Class1 中排除了 A,所以它对我不起作用。
如果原始 属性 已被隐藏,我将如何忽略它?
您可以使用 LINQ 查询来过滤掉隐藏的属性。
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();
在此处查看 运行:https://dotnetfiddle.net/V5sGIs
如果我理解你是对的,你需要 Class2
中的所有属性以及 Class1
中未在 Class2
您可以通过两次调用 GetProperties
来实现此目的:首先 select 全部在 Class2
中定义,然后访问 Class1
的类型并添加任何缺失的 [=19] =]
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);
}
}
如果您打印该列表
foreach (var propertyInfo in list)
Console.WriteLine($"From {propertyInfo.DeclaringType} > '{propertyInfo.Name}':{propertyInfo.PropertyType}");
您会看到如下内容:
From Class2 > 'B':System.Nullable`1[System.Boolean]
From Class1 > 'A':System.String
一个简单的基于 LINQ 的解决方案,它以通用的方式适用于所有 class 层次结构:
var propertiesWithoutHiddenOnes = GetProperties(objectToUpdate.GetType())
.GroupBy(prop => prop.Name)
.Select(group => group.Aggregate(
(mostSpecificProp, other) => mostSpecificProp.DeclaringType.IsSubclassOf(other.DeclaringType) ? mostSpecificProp : other))