通过字符串在对象列表中查找值

4

我需要从一个对象列表中找到最长的值,类似于这样...

var longestValue = list.Max(x => x.Name);

问题在于我不能像这样直接访问它,而是需要在循环中进行。以下是我目前的代码...
        public static void SetPropertyValue(this object obj, string propName, object value)
    {
        obj.GetType().GetProperty(propName).SetValue(obj, value, null);
    }


        var user = new User();

        var list = new List<User>
        {
            new Svedea {Name = "Steve", Car = "Volkswagen"},
            new Svedea {Name = "Denice Longhorn", Car = "Tesla"},
            new Svedea {Name = "Rebecca", Car = "Ford"},
            new Svedea {Name = "Mike O", Car = "Mercedes-Benz"}
        };

        var properties = user.GetType().GetProperties();
        var propList = properties.Select(pi => pi.Name).ToList();

        var newUser = new User();

        foreach (var row in propList)
        {
            // Here I need to find the longest value from the list above like this...
            // var longestValue = list.Max(x => x.row); // This is obviously not correct but I need to find this value needs to be found dynamically

            var longestValue = list.Max(x => x.row);
            newUser.SetPropertyValue(row, longestValue);

        }

目的是创建一个新的“用户”,该用户具有每个属性中最长的值。如果有多个值,则只使用第一个值。 - MTplus
是的,那是正确的。 - MTplus
那么你为什么要使用反射?提供的答案是否符合您的需求? - TheGeneral
提供的答案无法使用,因为它们直接通过propertyName访问User类,而User类可能会发生变化,可能会添加更多属性,我希望有一种通用的方法来创建一个包含每个属性最长值的单个User对象。 - MTplus
目前只有字符串值。 - MTplus
显示剩余3条评论
2个回答

0
使用LINQ的OrderByDescending方法,按照NameCar中最长的值对列表进行排序。然后,您可以创建一个新用户longestUser,该用户具有NameCar中最长的值:
var longestName = list.OrderByDescending(x => x.Name.Length).First().Name;
var longestCar = list.OrderByDescending(x => x.Car.Length).First().Car;
var longestUser = new User() { Name = longestName, Car = longestCar };

longestUser:

姓名 = "Denice Longhorn"

汽车 = "Mercedes-Benz"

编辑:

我已经修改了上面的解决方案,以便您可以使用字符串值访问属性名称:

var longestNameUser = list.OrderByDescending(x => x.GetType().GetProperty("Name").GetValue(x, null).ToString().Length).First();
var longestName = longestNameUser.GetType().GetProperty("Name").GetValue(longestNameUser, null);

var longestCarUser = list.OrderByDescending(x => x.GetType().GetProperty("Car").GetValue(x, null).ToString().Length).First();
var longestCar = longestCarUser.GetType().GetProperty("Car").GetValue(longestCarUser, null);

var newUser = new User();
PropertyInfo propertyInfo;

propertyInfo = newUser.GetType().GetProperty("Name");
propertyInfo.SetValue(newUser, Convert.ChangeType(longestName, propertyInfo.PropertyType), null);

propertyInfo = newUser.GetType().GetProperty("Car");
propertyInfo.SetValue(newUser, Convert.ChangeType(longestCar, propertyInfo.PropertyType), null);

您修改后的for循环:

var newUser = new User();
PropertyInfo propertyInfo;

foreach (var row in propList)
{
    var longestValueUser = list.OrderByDescending(x => x.GetType().GetProperty(row).GetValue(x, null).ToString().Length).First();
    var longestValue = longestValueUser.GetType().GetProperty(row).GetValue(longestValueUser, null);
    propertyInfo = newUser.GetType().GetProperty(row);
    propertyInfo.SetValue(newUser, Convert.ChangeType(longestValue, propertyInfo.PropertyType), null);
}

更好的写法是 var longestCar = list.OrderByDescending(x => x.Car.Length).First().Car; 吗? - Cid
抱歉,但是这个建议的解决方案对我不起作用,我需要能够使用字符串访问最长的值,而不是直接使用属性名称。 - MTplus
1
非常感谢,这帮了很大的忙 :) - MTplus
@MTplus 我不是指你,是其他人给我点了踩。我很高兴我能帮到你! - Slaven Tojić

0
你可以通过泛型和反射的混合使用来实现类似这样的功能。 示例
public static T CreateType<T>(List<T> list) where T : new ()
{
   var obj = new T();

   var type = typeof(T);
   var properties = type.GetProperties();

   foreach (var prop in properties)
   {
      var value = list.Select(x => x.GetType()
                                    .GetProperties()
                                    .First(y => y == prop)
                                    .GetValue(x) as string)
                      .OrderByDescending(x => x.Length)
                      .First();

      var propInstance = obj.GetType()
                            .GetProperties()
                            .First(x => x == prop);

      propInstance.SetValue(obj, value);
   }

   return obj;
}

使用方法

var someList = new List<SomeClass>()
                  {
                     new SomeClass()
                        {
                           Name = "asd",
                           Car = "sdfsdf"
                        },
                     new SomeClass()
                        {
                           Name = "dfgfdg",
                           Car = "dfgdf"
                        }
                  };


var SomeClass = CreateType(someList);

输出

some value 1 longer, Some value 2 longer

完整演示请点击此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接