C#实现通用方法:无需指定属性即可打印LINQ结果到控制台
搞定任意类集合的属性值打印问题
我懂你想要的效果——一个万能方法,不管用LINQ查出来的是什么类的集合,都能把所有属性名和对应值整齐打印到控制台。之前用反射的思路是对的,问题出在没用到泛型来适配任意类型,导致参数没法灵活支持var声明的变量。
直接上完整的解决方案代码,你可以直接复用:
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; public static class CollectionPrinter { // 泛型方法,支持任意类型的枚举集合 public static void PrintTable<T>(IEnumerable<T> items) { if (items == null || !items.Any()) { Console.WriteLine("集合为空或不存在"); return; } // 获取当前类型的所有公共实例属性 PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); if (properties.Length == 0) { Console.WriteLine("该类型没有公共属性"); return; } // 打印表头:左对齐固定宽度20,保证排版整齐 foreach (var prop in properties) { Console.Write($"{prop.Name,-20}"); } Console.WriteLine(); Console.WriteLine(new string('-', properties.Length * 20)); // 打印分隔线 // 遍历每个元素,打印对应属性值 foreach (var item in items) { foreach (var prop in properties) { var value = prop.GetValue(item) ?? "null"; // 处理null值,避免空输出 Console.Write($"{value.ToString(),-20}"); } Console.WriteLine(); } } } // 测试用例类 public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public DateTime JoinDate { get; set; } } public class Product { public string ProductId { get; set; } public string ProductName { get; set; } public decimal Price { get; set; } public bool InStock { get; set; } } class Program { static void Main() { // 用LINQ筛选Person集合 var people = new List<Person> { new Person { Id = 1, Name = "Alice", Age = 28, JoinDate = new DateTime(2022, 3, 15) }, new Person { Id = 2, Name = "Bob", Age = 35, JoinDate = new DateTime(2021, 10, 20) } }.Where(p => p.Age > 30); Console.WriteLine("===== Person集合打印结果 ====="); CollectionPrinter.PrintTable(people); // 用LINQ筛选Product集合 var products = new List<Product> { new Product { ProductId = "P001", ProductName = "Laptop", Price = 999.99m, InStock = true }, new Product { ProductId = "P002", ProductName = "Mouse", Price = 25.5m, InStock = false } }.Where(p => p.Price < 100); Console.WriteLine("\n===== Product集合打印结果 ====="); CollectionPrinter.PrintTable(products); } }
核心细节说明:
- 泛型适配任意类型:
PrintTable<T>接收IEnumerable<T>参数,不管你用var声明的是List<Person>还是LINQ返回的IQueryable<Product>,都能完美兼容,这就是你要的“支持var”的关键。 - 反射获取属性:用
typeof(T).GetProperties()获取泛型类型的公共属性,保证表头和每行的属性一一对应。如果需要包含非公共属性,可以调整BindingFlags参数(比如加上BindingFlags.NonPublic)。 - null值友好处理:用
?? "null"把null值转换成可读性强的字符串,避免控制台出现空白。 - 排版优化:通过
-20实现左对齐并固定宽度,让输出的表格整齐易读。
你之前可能踩的坑:
如果之前的方法没用到泛型,而是用object或特定类型做参数,就没法灵活接收各种LINQ查询结果;另外如果用item.GetType().GetProperties(),当集合里有派生类实例时,会打印派生类的额外属性,而用typeof(T)则会严格按照声明的类型打印属性,你可以根据需求选择。
如果需要更定制化的效果(比如跳过某些属性、格式化日期/数字),还可以给方法加参数或者用特性标记来控制,这个基础版本已经能满足大部分场景啦!
内容的提问来源于stack exchange,提问作者Hapkin
相关产品推荐
相关产品推荐

