c#:将不同的类解析为对象,并以相同的方式显示属性值
本文关键字:方式 显示 属性 对象 | 更新日期: 2023-09-27 18:12:27
我在c#控制台应用程序中有几个类。
public class Cars:List<Car>
{}
:
public class Drivers:List<Driver>
{}
目标是始终以相同的方式呈现控制台输出,无论cars
或drivers
是否被解析为呈现方法。所以参数类型为object
。当然,属性可以有不同的名称。
输出应该像这样:
// Cars
Brand HP Topspeed
VW 100 200
VW 90 150
或
// Drivers
Name Age Sex
Pit 18 m
Jane 20 f
所以我需要读取属性名以使它们成为列标题,然后读取每个对象的值。我已经搜索了一段时间,总是出现这样的东西:
public static void RenderOutput(object obj)
{
foreach (var prop in obj.GetType().GetProperties())
{
}
}
虽然在运行时鼠标悬停在obj
上显示所有所需的对象和属性(品牌,HP,大众,100,…)非常好,但我无法通过car
或driver
从prop
项目car
中挤出driver
的值。
任何建议吗?谢谢jimbo2015
我建议去interface
路由,有一个接口,将有方法RenderOutput
。汽车和驾驶员都将实现该接口,并提供它们自己的方法实现。这将是更合适的,因为汽车方法将不知道司机或签证-verse。在调用方法时,不是传递对象,而是调用实例方法。
在使用反射时应该使用BindingFlags
,以便获得实例的属性。例如,要获取object o
的所有private
属性,您应该使用:
IEnumerable<PropertyInfo> props = o.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic);
foreach (PropertyInfo info in props)
{
Console.WriteLine(info.Name + info.GetValue(o));
}
说了这些之后,请注意,为打印方法使用Car
和Driver
实现的interface
可能是更正确的设计。如果您想使用反射,我建议在您想要打印的属性上添加Attributes
,并使用所需的显示名称,以便将显示与代码的命名约定分开。
正确的方法是实现一个接口(如@Adarsha所说),并在每个类中实现RenderOutput()方法,使其具有自己的特定实现,具有正确的属性列表,正确的格式等。
现在,如果你仍然想坚持你的方法,这是可行的。
让我们假设这些是你的类
public class Car
{
public string Brand { get; set; }
public int HorsePower { get; set; }
public int TopSpeed { get; set; }
}
public class Driver
{
public string Name { get; set; }
public int Age { get; set; }
public string Sex { get; set; }
}
现在,这些方法将使用反射来读取属性并在控制台中写入它们。
public static void RenderOutput(IEnumerable<object> collection)
{
RenderHeader(collection.First()); //collection not validated
collection.ToList().ForEach(item => RenderBody(item));
}
private static void RenderHeader(object obj)
{
var properties = obj.GetType().GetProperties().OrderBy(p => p.Name);
Console.WriteLine("");
foreach (var prop in properties)
{
Console.Write(prop.Name + "'t"); //or ("{0,15}", prop.Name)
}
}
private static void RenderBody(object obj)
{
var properties = obj.GetType().GetProperties().OrderBy(p => p.Name);
Console.WriteLine("");
foreach (var prop in properties)
{
Console.Write((prop.GetValue(obj, null)) + "'t"); //or ("{0,15}", (prop.GetValue(obj, null)))
}
}
您现在可以在任何IEnumerable<T>
上调用RenderOutput()
方法来获得所需的输出。你可以像这样测试
static void Main(string[] args)
{
//test data
var cars = new List<Car>();
cars.Add(new Car { Brand = "BMW", HorsePower = 100, TopSpeed = 200 });
cars.Add(new Car { Brand = "VW", HorsePower = 90, TopSpeed = 150 });
var drivers = new List<Driver>();
drivers.Add(new Driver { Name = "Prit", Age = 18, Sex = "Male" });
drivers.Add(new Driver { Name = "Jane", Age = 20, Sex = "Female" });
RenderOutput(cars);
Console.WriteLine();
RenderOutput(drivers);
Console.ReadLine();
}
这是生成的输出:
Brand HorsePower TopSpeed
BMW 100 200
VW 90 150
Age Name Sex
18 Prit Male
20 Jane Female
注意:这对复杂类型的属性不起作用!