如何更新对象列表中具有特定值的所有字段

时间:2017-06-26 17:22:10

标签: c# list linq reflection

我有一个对象列表,我想将所有字段“null”更新为string.empty。

这是代码:

public class Class1
{
    public string P1 { get; set; }
    public string P2 { get; set; }
    public string P3 { get; set; }
}

我希望有一个代码可以找到所有字段中的所有空值并将值更改为string.empty

     static void Main(string[] args)
    {

        var list= new List<Class1>();
        var class1 = new Class1 {P1 = "P1-1", P2 = "P2-1", P3="null"};
        list.Add(class1);
        var class2 = new Class1 { P1 = "P1-2", P2 = "P2-2", P3 = "null" };
        list.Add(class2);

    }

所以我需要找到class1.P3和class2.P3并替换它们的值。

由于

2 个答案:

答案 0 :(得分:3)

您可以编写如下的简短通用函数:

private static IEnumerable<TSource> ReplaceValues<TSource>(IEnumerable<TSource> source, object oldValue,
    object newValue)
{
    var properties = typeof(TSource).GetProperties();
    foreach (var item in source)
    {
        foreach (var propertyInfo in properties.Where(t => Equals(t.GetValue(item), oldValue)))
        {
            propertyInfo.SetValue(item, newValue);
        }
        yield return item;
    }
}

这比你的更有效,因为你的集合类型是TSource,这意味着里面的所有类型都具有相同的属性。获取和缓存这些属性将加快此过程,因为您只需拨打Type.GetProperties()一次,而不是您正在操作和过滤这些结果。

<强>更新

正如下面的评论部分Ivan Stoev所讨论的那样,让方法修改集合而不返回任何值会更合适:

private static void ReplaceValues<TSource>(IEnumerable<TSource> source, object oldValue,
    object newValue)
{
    var properties = typeof(TSource).GetProperties();
    foreach (var item in source)
    {
        foreach (var propertyInfo in properties.Where(t => Equals(t.GetValue(item), oldValue)))
        {
            propertyInfo.SetValue(item, newValue);
        }
    }
}

答案 1 :(得分:0)

这将照顾它:

   static void Main(string[] args)
    {

        var list= new List<Class1>();
        var class1 = new Class1 {P1 = "P1-1", P2 = "P2-1", P3="null"};
        list.Add(class1);
        var class2 = new Class1 { P1 = "P1-2", P2 = "P2-2", P3 = "null" };
        list.Add(class2);


        foreach (var item in list)
        {
            var props2 = from p in item.GetType().GetProperties()
                        let attr = p.GetValue(item)
                        where attr != null && attr.ToString() == "null"
                        select p;

            foreach (var i in props2)
            {
                i.SetValue(item, string.Empty);
            }
        }
    }

UPDATE ::::

这是一种更有效的方式。

    static void Main(string[] args)
    {

            var list = new List<Class1>();
            var class1 = new Class1 {P1 = "P1-1", P2 = "P2-1", P3 = "null"};
            list.Add(class1);
            var class2 = new Class1 {P1 = "P1-2", P2 = "P2-2", P3 = "null"};
            list.Add(class2);



           var updatedList=  ReplaceValues(list, "null", string.Empty);

    }

    private static IEnumerable<TSource> ReplaceValues<TSource>
    (IEnumerable<TSource> source, object oldValue,
    object newValue)
    {
        var properties = typeof(TSource).GetProperties();
        var sourceToBeReplaced = source as TSource[] ?? source.ToArray();
        foreach (var item in sourceToBeReplaced)
        {
            foreach (var propertyInfo in properties.Where(t => Equals(t.GetValue(item), oldValue)))
            {
                propertyInfo.SetValue(item, newValue);
            }
        }

        return sourceToBeReplaced;
    }