如何知道 PropertyInfo 是否是一个集合

下面是我用来获取 IsDirty 检查类中所有公共属性的初始状态的一些代码。

What's the easiest way to see if a property is IEnumerable?

干杯,
Berryl

  protected virtual Dictionary<string, object> _GetPropertyValues()
{
return _getPublicPropertiesWithSetters()
.ToDictionary(pi => pi.Name, pi => pi.GetValue(this, null));
}


private IEnumerable<PropertyInfo> _getPublicPropertiesWithSetters()
{
return GetType().GetProperties().Where(pi => pi.CanWrite);
}

UPDATE

我最后要做的是添加一些库扩展,如下所示

    public static bool IsNonStringEnumerable(this PropertyInfo pi) {
return pi != null && pi.PropertyType.IsNonStringEnumerable();
}


public static bool IsNonStringEnumerable(this object instance) {
return instance != null && instance.GetType().IsNonStringEnumerable();
}


public static bool IsNonStringEnumerable(this Type type) {
if (type == null || type == typeof(string))
return false;
return typeof(IEnumerable).IsAssignableFrom(type);
}
39426 次浏览
if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType != typeof(string))

试试看

private bool IsEnumerable(PropertyInfo pi)
{
return pi.PropertyType.IsSubclassOf(typeof(IEnumerable));
}

我同意 Fyodor Soikin 的观点,但是事实上是可枚举的并不意味着它只是一个集合,因为字符串也是可枚举的,并且逐个返回字符..。

所以我建议用

if (typeof(ICollection<>).IsAssignableFrom(pi.PropertyType))

你也可以使用“模式匹配”,这对 List<T>IEnumerable<T>都适用。

private void OutputPropertyValues(object obj)
{
var properties = obj.GetType().GetProperties();


foreach (var property in properties)
{
if (property.GetValue(obj, null) is ICollection items)
{
_output.WriteLine($"    {property.Name}:");


foreach (var item in items)
{
_output.WriteLine($"        {item}");
}
}
else
{
_output.WriteLine($"    {property.Name}: {property.GetValue(obj, null)}");
}
}
}