2015-09-13 2 views
1

У меня есть несколько классов в консольном приложении C#.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()) 
    { 
    } 
} 

Хотя во время выполнения Mouseover obj показывает все нужные объекты и свойства (марка, HP, VW, 100, ...) очень хорошо, я не удается сжать значения из prop, пункт car, по car или driver по driver.

Любое предложение? Thx jimbo2015

ответ

2

Я хотел бы предложить собирается interface маршрут, иметь интерфейс, который будет иметь метод RenderOutput. Оба автомобиля и драйверы реализуют интерфейс и предоставляют свои собственные реализации этого метода. Это будет более уместно, поскольку метод автомобилей не будет знать о драйвере или визе. Когда вы вызываете метод, вместо передачи объекта вы вызываете метод экземпляра.

1

Вы должны использовать BindingFlags при использовании отражения, чтобы получить свойства экземпляра. например, чтобы получить все private свойства object o вы должны использовать:

IEnumerable<PropertyInfo> props = o.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic); 
foreach (PropertyInfo info in props) 
{ 
    Console.WriteLine(info.Name + info.GetValue(o)); 
} 

Сказав это, заметьте, что наличие interface, который будет реализован с помощью Car и Driver для метода печати является, вероятно, более правильно дизайн-накрест , Если вы хотите использовать отражение в любом случае, я бы рекомендовал добавить Attributes по свойствам, которые вы хотите распечатать, с желаемым отображаемым именем, чтобы разделить экран на соглашения об именах кода.

1

Правильный подход будет реализован интерфейс (как @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; } 
} 

Теперь эти методы будут использовать отражение для чтения свойств и writethem в консоли.

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))) 
    } 
} 

Теперь вы можете вызвать метод RenderOutput() на любой IEnumerable<T>, чтобы получить желаемый результат. Вы можете проверить это, как этот

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 

Примечание: Это не будет работать для сложных свойств типа!

Смежные вопросы