2

I have an object called Job and inside of it I have strings, ints, and an enum as public objects. Each job is then placed into a Queue and I iterate through the queue in the process.

What I want to do is that when I Dequeue() each job, I can generically iterate through each job and write the public object names and values to the console.

I figured out how to write the object names to console and I can obviously write the values, but the problem is that I don't know how to get each public string/int/enum from the Job object.

I've looked at C# object dumper C#: How to get all public (both get and set) string properties of a type How to select all the values of an object's property on a list of typed objects in .Net with C# but don't understand how I would use either of the accepted answers there.

Here's the code to my Job class:

    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
    }

Here's the code that's returning the variable's name: (from 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;
}

Ideally I'd have an output to console like this:

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

Thoughts?

Community
  • 1
  • 1
cvocvo
  • 1,586
  • 2
  • 23
  • 38
  • use reflection to iterate through the properties, get the value, use it's tostring() method. Or override toString (or an another method) that builds a nice output from the class. Course you'll have to maintain that... – Tony Hopkinson Jan 03 '12 at 17:34
  • I think I'm gradually getting it via looking at the example here: http://msdn.microsoft.com/en-us/library/aa332475(v=vs.71).aspx I'll post my solution when I get it. – cvocvo Jan 03 '12 at 17:50
  • 2
    Why can't you just override [ToString](http://msdn.microsoft.com/en-us/library/system.object.tostring.aspx) (or write a similar method with a different name) in your `Job` class? – Matthew Strawbridge Jan 03 '12 at 18:40

2 Answers2

3

What I think you're looking for is PropertyInfo.GetValue. Perhaps something like this will help (from memory so hopefully it'll work as is):

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

You can also something similar with your object's fields if you tend to use those instead of properties.

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

These will dump to the console, but it should be straight forward enough to change them to write to any stream.

Update

If you start getting NullReferenceException's from a property not being set, rather than wrapping it in a try...catch, you should do some proactive checks against the value returned from 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);
    }
}
M.Babcock
  • 18,753
  • 6
  • 54
  • 84
  • I'm not always initializing all values in Jobs so your first DumpProperties method throws a NullReferenceException, but I'm just handling that as follows: void DumpProperties(Object dumpWhat) { foreach (PropertyInfo prop in dumpWhat.GetType().GetProperties()) { try { Console.WriteLine("{0} = {1}", prop.Name, prop.GetValue(dumpWhat, BindingFlags.GetProperty, null, null, null).ToString()); } catch (NullReferenceException) { } } } – cvocvo Jan 03 '12 at 19:06
  • @cvocvo - A cleaner way of handling that would be to first get the object from GetValue, check if it is null, and if it isn't then convert it to a string. The only reason this is cleaner is because Exceptions and Exception handling are expensive. I'll update my answer with an example of how I would handle that situation. – M.Babcock Jan 03 '12 at 19:14
1

Per the suggestion of Tony Hopkinson, you may add the following method override to your Job class:

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

Then, before you queue you may:

    Console.WriteLine( job1 );
Wildly Stunted
  • 147
  • 1
  • 6