2015-05-27 78 views
3

我想创建一个属性验证器,给定一个列表,必须确保该列表至少有一个元素。通过IList动态属性迭代

所以,我有这样的时刻

public override bool IsValid(object value) 
{ 
    var list = value as IList; 

    if (list != null) 
     return list.Count >= 1; 

    return false; 
} 

我的问题是,我可以接收多个元素的列表,但所有这些元素的属性是空的,所以我需要遍历在每个属性上检查它们。而且我不确定如何在不知道房产名称的情况下实现这一目标。

+0

public override bool IsValid(IEnumerable<MyType> myObjects) 

其次,由一种叫做IsEmpty属性提升自己的类型你得到什么物体?一个自定义的?如果是这样,你不能也提供一个名为'IsEmpty'的属性吗? –

+0

我不太清楚你的属性是什么意思。是否意味着列表的实际元素不应该是非空的,或者你想检查每个元素的每个属性是否为非null? –

回答

1

根据您的意见,您有一个自定义类型。首先,在你的方法声明中使用它,而不要使用一个对象。类型转换以及装箱和拆箱是昂贵的:

public class MyType 
{ 
    public bool IsEmpty 
    { 
     get 
     { 
      // define here when your type is empty 
     } 
    } 

    ... 
} 

那么你最后的检查很简单:

public override bool IsValid(IEnumerable<MyType> myObjects) 
{ 
    return myObjects != null ? myObjects.Any() : false; 
} 
+1

是的,是一种自定义类型,我使用的是一个对象,因为我需要将它用于多个viewModel,所以我一直在寻找更一般的解决方案。但我想我会尝试这种方式,我让你知道,谢谢! – fmasche

-1

我建议使用IEnumerable,只是因为它可以与其他列表一起使用。

但除此之外。您可以使用枚举数,它存在于每个可枚举数上。只要你找到第一个非空元素,返回true:

public override bool IsValid(object value) 
{ 
    var list = value as IEnumerable; 
    var enumerator = list != null ? list.GetEnumerator() : null; 

    if (enumerator != null) 
     while(enumerator.MoveNext()) 
      if(enumerator.Current != null) 
       return true; 

    return false; 
} 

第二个想法,你可能会做得更好。通过你的清单上调用Cast<object>()你得到一个通用IEnumerable<object>上,您可以使用所有强大的LINQ的并调用Count(e => e != null)您枚举:

public override bool IsValid(object value) 
{ 
    var list = value as IEnumerable; 
    var enumerable = list != null ? list.Cast<object>() : null; 
    return enumerable != null && enumerable.Count(e => e != null) >= 1; 
} 
+0

这是如何解决问题的?你在哪里检查孩子属性为空/空? –

+0

im在最后一行使用'enumerable.Count(e => e!= null)'计算所有非空元素(第二个例子...第一个元素在枚举器中找到非null元素后立即返回true )...实际上在之前忘记了> = 1,修正了 –

+0

抱歉,刚刚意识到我错过了这个问题......如果明天仍然需要答案,我会修复这个问题......现在需要睡觉.. –