You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

泛型List<>扩展方法简化及对象属性批量提取技术问询

简化泛型扩展方法,仅指定返回类型

针对你想要简化泛型List扩展方法的需求,我整理了一个更简洁的实现——只需要指定返回值类型T,不需要额外指定列表元素的类型,完美贴合你期望的selectAll<T>(this List<anyType>, ...)形式。

实现代码

我们可以基于非泛型的IEnumerable来编写扩展方法,这样能兼容任意类型的List(包括值类型和引用类型):

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

public static class ListExtensions
{
    public static T[] SelectAll<T>(this IEnumerable list, string propertyName)
    {
        // 参数合法性校验
        if (list == null)
            throw new ArgumentNullException(nameof(list), "源列表不能为null");
        if (string.IsNullOrWhiteSpace(propertyName))
            throw new ArgumentException("属性名称不能为null或空白字符", nameof(propertyName));

        var resultList = new List<T>();

        foreach (var item in list)
        {
            if (item == null)
            {
                // 处理null元素:默认添加T类型的默认值,可根据需求修改为跳过/抛出异常
                resultList.Add(default(T));
                continue;
            }

            // 获取元素类型的指定公共实例属性
            PropertyInfo prop = item.GetType().GetProperty(
                propertyName,
                BindingFlags.Public | BindingFlags.Instance
            );

            if (prop == null)
            {
                throw new InvalidOperationException(
                    $"类型'{item.GetType().FullName}'中未找到公共实例属性'{propertyName}'"
                );
            }

            // 提取属性值并转换为目标类型T
            object propertyValue = prop.GetValue(item, null);
            resultList.Add((T)Convert.ChangeType(propertyValue, typeof(T), CultureInfo.InvariantCulture));
        }

        return resultList.ToArray();
    }
}

使用示例

不管你的List存储的是自定义类、值类型还是其他对象,都可以直接调用这个方法,仅需指定返回类型:

// 自定义类示例
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// 实际调用场景
List<Person> people = new List<Person>
{
    new Person { Name = "Alice", Age = 30 },
    new Person { Name = "Bob", Age = 25 }
};

// 提取Name属性,返回string[]
string[] names = people.SelectAll<string>("Name");
// 提取Age属性,返回int[]
int[] ages = people.SelectAll<int>("Age");

// 值类型List示例(注意:值类型本身需存在指定属性,比如int没有Name属性,调用会抛异常)
List<DateTime> dates = new List<DateTime> { DateTime.Now, DateTime.Now.AddDays(1) };
// 提取Date属性,返回DateTime[]
DateTime[] dateValues = dates.SelectAll<DateTime>("Date");

关键说明

  1. 泛型简化:通过基于非泛型IEnumerable扩展,我们不再需要指定列表元素的泛型参数,仅需关注返回值类型T,完全满足你的简化需求。
  2. 兼容性拉满:支持所有实现IEnumerable的集合(包括List<T>、ArrayList等),不管元素是引用类型还是值类型。
  3. 健壮性保障:添加了参数校验、null元素处理和属性不存在的异常提示,调试时更清晰。
  4. 安全类型转换:使用Convert.ChangeType配合InvariantCulture,确保属性值能安全转换为目标类型T,避免区域化导致的转换问题。

注意事项

  • 如果列表中存在元素没有指定的公共实例属性,方法会抛出InvalidOperationException,调用前需确保所有元素都包含该属性。
  • 如果属性值无法转换为T类型(比如把字符串"abc"转成int),Convert.ChangeType会抛出InvalidCastException,需确保类型转换的合理性。
  • 针对null元素的处理逻辑可以根据你的需求修改,比如改成跳过null元素,或者直接抛出异常。

内容的提问来源于stack exchange,提问作者Ben Philipp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:56:54