Записать значения всех открытых объектов (string / int / enum) внутри объекта контейнера в консоль - PullRequest
2 голосов
/ 03 января 2012

У меня есть объект с именем Job, и внутри него у меня есть строки, целые числа и перечисление как публичные объекты.Затем каждое задание помещается в очередь, и в процессе я выполняю итерацию по очереди.

Что я хочу сделать, так это то, что когда я снимаю () с каждого задания, я могу обобщенно выполнять итерацию по каждому заданию и писать открытыеимена и значения объектов в консоли.

Я выяснил, как записать имена объектов в консоль, и я, очевидно, могу записать значения, но проблема в том, что я не знаю, как получить каждую открытую строку /int / enum из объекта Job.

Я смотрел на C # dumper объекта C #: Как получить все открытые (как получить, так и установить) строковые свойства типа Как выбрать все значения свойства объекта в списке типизированных объектов в .Net с C # , но не понимаю, как бы я использовал один из принятых ответов там.

Вот код моего класса Job:

    class Job
    {
       #region Constructor
       public Job()
       {
       }
       #endregion

       #region Accessors
       public int var_job { get; set; }
       public jobType var_jobtype { get; set; } //this is an enum
       public string var_jobname { get; set; }
       public string var_content { get; set; }
       public string var_contenticon { get; set; }
       #endregion
    }

Вот код, который возвращает имя переменной: (из https://stackoverflow.com/a/2664690/559988)

GetName(new {Job.var_content}) //how I call it
static string GetName<T>(T item) where T : class
{
    return typeof(T).GetProperties()[0].Name;
}

В идеале, у меня будет вывод на консолькак это:

Queuing Jobs Now
--------------------
var_job = its value
var_jobtype = its value
var_jobname = its value
var_content = its value
var_contenticon = its value

Thoughts?

Ответы [ 2 ]

3 голосов
/ 03 января 2012

Я думаю, что вы ищете PropertyInfo.GetValue. Возможно, что-то подобное поможет (по памяти, надеюсь, оно будет работать как есть):

public static void DumpProperties(this Object dumpWhat)
{
    foreach(PropertyInfo prop in dumpWhat.GetType().GetProperties())
        Console.WriteLine("{0} = {1}", prop.Name, prop.GetValue(dumpWhat, BindingFlags.GetProperty, null, null, null).ToString());
}

Вы также можете сделать что-то похожее с полями вашего объекта, если вы склонны использовать их вместо свойств.

public static void DumpFields(this Object dumpWhat)
{
    foreach(FieldInfo fld in dumpWhat.GetType().GetFields())
        Console.WriteLine("{0} = {1}", fld.Name, fld.GetValue(dumpWhat, BindingFlags.GetField, null, null, null).ToString());
}

Они будут выгружаться в консоль, но это должно быть достаточно просто, чтобы изменить их для записи в любой поток.

Обновление

Если вы начнете получать NullReferenceException из свойства, которое не было установлено, вместо того, чтобы обернуть его в try...catch, вам следует провести некоторые упреждающие проверки относительно значения, возвращенного из PropertyInfo.GetValue:

public static void DumpProperties(this Object dumpWhat)
{
    foreach(PropertyInfo prop in dumpWhat.GetType().GetProperties())
    {
        string propVal = prop.GetValue(dumpWhat, BindingFlags.GetProperty, null, null, null) as string;

        if (propVal != null)
            Console.WriteLine("{0} = {1}", prop.Name, propVal);
    }
}
1 голос
/ 03 января 2012

По предложению Тони Хопкинсона вы можете добавить следующий метод переопределения к вашему классу заданий:

    public override string ToString()
    {
        string foo =
            string.Format( "var_job = {1}{0}var_jobType = {2}{0}var_jobname = {3}{0}var_content = {4}{0}var_contenticon = {5}{0}",
                Environment.NewLine,
                this.var_jobname,
                this.jobType,
                this.var_jobname,
                this.var_content,
                this.var_contenticon );

        return foo;
    }

Затем, прежде чем встать в очередь, вы можете:

    Console.WriteLine( job1 );
...