如何在 T 变化的一堆 ISet<T> 属性上调用 Count
How to call Count on a bunch of ISet<T> properties where T varies
我有一个 class,它有一堆 ISet<T>
类型的属性,其中 T 从 属性 到 属性。
我想遍历一个对象的属性,找到某种 ISet
的属性,然后对每个属性调用 Count。
谢谢。
这可能有效,obj
是一个目标对象:
Type targetType = obj.GetType();
foreach (var propertyInfo in targetType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy))
{
var isetInterface = propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ISet<>)
? propertyInfo.PropertyType
: null;
if(isetInterface == null)
{
isetInterface = propertyInfo.PropertyType
.GetInterfaces()
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ISet<>));
}
if (isetInterface != null)
{
object isetPropertyValue = propertyInfo.GetValue(obj);
var countPropertyInfo = isetInterface
.GetInterfaces()
.First(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>))
.GetProperty("Count");
if (isetPropertyValue == null)
{
Console.WriteLine($".{propertyInfo.Name} == null");
}
else
{
var count = countPropertyInfo.GetValue(isetPropertyValue);
Console.WriteLine($".{propertyInfo.Name}.Count == {count}");
}
}
}
@Renat 的回答对我有用,但我将其调整为我觉得更方便的内容:
public virtual string counts => typeof(Changeset)
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy)
.Where(prop => prop.GetValue(this) != null && count(prop) > 0)
.Select(prop => $@".{prop.Name}.Count == {count(prop)}")
.Join("\n");
private int count(PropertyInfo prop)
{
var name = prop.Name;
var isetInterface = prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(ISet<>)
? prop.PropertyType
: null;
if (isetInterface == null)
{
isetInterface = prop.PropertyType
.GetInterfaces()
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ISet<>));
}
if (isetInterface != null)
{
object isetPropertyValue = prop.GetValue(this);
var countPropertyInfo = isetInterface
.GetInterfaces()
.First(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>))
.GetProperty("Count");
if (isetPropertyValue == null)
return 0;
else
return (int) countPropertyInfo.GetValue(isetPropertyValue);
}
return 0;
}
此外,我发现如果我可以按名称引用属性,我就可以使用
private string count<T>(Func<Changeset, ISet<T>> selector)
{
var count = selector(this).Count;
return count > 0 ? $"\n{typeof(T).Name}s:\t\t{count}" : "";
}
如
$"{count(x => x.prop)}"
我有一个 class,它有一堆 ISet<T>
类型的属性,其中 T 从 属性 到 属性。
我想遍历一个对象的属性,找到某种 ISet
的属性,然后对每个属性调用 Count。
谢谢。
这可能有效,obj
是一个目标对象:
Type targetType = obj.GetType();
foreach (var propertyInfo in targetType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy))
{
var isetInterface = propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ISet<>)
? propertyInfo.PropertyType
: null;
if(isetInterface == null)
{
isetInterface = propertyInfo.PropertyType
.GetInterfaces()
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ISet<>));
}
if (isetInterface != null)
{
object isetPropertyValue = propertyInfo.GetValue(obj);
var countPropertyInfo = isetInterface
.GetInterfaces()
.First(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>))
.GetProperty("Count");
if (isetPropertyValue == null)
{
Console.WriteLine($".{propertyInfo.Name} == null");
}
else
{
var count = countPropertyInfo.GetValue(isetPropertyValue);
Console.WriteLine($".{propertyInfo.Name}.Count == {count}");
}
}
}
@Renat 的回答对我有用,但我将其调整为我觉得更方便的内容:
public virtual string counts => typeof(Changeset)
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy)
.Where(prop => prop.GetValue(this) != null && count(prop) > 0)
.Select(prop => $@".{prop.Name}.Count == {count(prop)}")
.Join("\n");
private int count(PropertyInfo prop)
{
var name = prop.Name;
var isetInterface = prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(ISet<>)
? prop.PropertyType
: null;
if (isetInterface == null)
{
isetInterface = prop.PropertyType
.GetInterfaces()
.FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ISet<>));
}
if (isetInterface != null)
{
object isetPropertyValue = prop.GetValue(this);
var countPropertyInfo = isetInterface
.GetInterfaces()
.First(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>))
.GetProperty("Count");
if (isetPropertyValue == null)
return 0;
else
return (int) countPropertyInfo.GetValue(isetPropertyValue);
}
return 0;
}
此外,我发现如果我可以按名称引用属性,我就可以使用
private string count<T>(Func<Changeset, ISet<T>> selector)
{
var count = selector(this).Count;
return count > 0 ? $"\n{typeof(T).Name}s:\t\t{count}" : "";
}
如
$"{count(x => x.prop)}"