设置对象的所有bool属性值

时间:2018-01-23 14:26:58

标签: c# reflection

考虑以下对象

public class Foo
{
    public bool RecordExist { get; set; }

    public bool HasDamage { get; set; }

    public bool FirstCheckCompleted { get; set; }

    public bool SecondCheckCompleted { get; set; }

    //10 more bool properties plus other properties
}

现在我想要实现的是将属性值设置为true,除boolRecordExist之外的所有HasDamage属性。为实现这一目标,我已经开始创建以下方法。

public T SetBoolPropertyValueOfObject<T>(string[] propNames, Type propertyType, object value)
{
   PropertyInfo[] properties = typeof(T).GetProperties();

   T obj = (T)Activator.CreateInstance(typeof(T));

    if(propNames.Length > 0 || propNames != null)
        foreach (var property in properties)
         foreach (string pName in propNames)
            if (property.PropertyType == propertyType && property.Name != pName)
                 property.SetValue(obj, value, null);

        return obj;
}

然后按如下方式调用上述方法:

public Foo Foo()
{
   string[] propsToExclude = new string[]
   {
      "RecordExist",
      "HasDamage"
   };

    var foo = SetBoolPropertyValueOfObject<Foo>(propsToExclude, typeof(bool), true);

    return foo;
}

该方法无法按预期工作。当第一次在foreach循环内时,RecordExist道具设置为false,但当它再次进入循环时,RecordExist设置为true,其余道具设置为true为包括HasDamage

有人能告诉我出错的地方吗。

2 个答案:

答案 0 :(得分:5)

你的逻辑错了:

  • 外环想要设置例如RecordExist
  • 内循环,第一步说&#34;哦,它等于RecordExist,我没有设置&#34;
  • 内循环,第二步:&#34;哦RecordExist不等于HasDamage所以我设置&#34;

您只想知道propNames 是否包含属性名称:

if(propNames.Length > 0 || propNames != null)
      foreach (var property in properties)
          if (property.PropertyType == propertyType && 
              !propNames.Contains(property.Name))
             property.SetValue(obj, value, null);

但请注意,如果您提供要排除的名称(外部if),则此设置只会设置任何属性。我不认为这就是你想要的。

所以最终的代码看起来像:

foreach (var property in properties.Where(p => 
                p.PropertyType == propertyType &&
                propNames?.Contains(p.Name) != true)) // without the 'if' we need a null-check
     property.SetValue(obj, value, null);

答案 1 :(得分:3)

使用单个循环:

@JoinTable