Get array of class variables

D

Daan

Say I have an Object of the following class:

public class SomeClass {
public string var1;
public int var2;
public SomeType var3;
}

Now I want to print all the three vars. Is it possible to get an array
containing these three vars, making something like this possible:

for (int i = 0; i < myArray.Length; i++) {
myPrintFunction(myArray);
}

Or is there no other option then to print each class variable
explicitly, like this:

myPrintFunction(myObject.var1);
myPrintFunction(myObject.var2);
myPrintFunction(myObject.var3);

My guess would be that the Reflection library makes such a thing
possible, but I could not find it there.

Regards,

Daan
 
V

ViRi

foreach (object o in SomeClass)
{
myPrintFunction(o);
}

think something like this should work.
 
P

Peter Rilling

You can override the ToString() method so that it prints out information
appropriate to your object. Then you can just call myObject.ToString(), or
are you looking for something more generic?
 
D

Daan

Peter said:
You can override the ToString() method so that it prints out information
appropriate to your object. Then you can just call myObject.ToString(), or
are you looking for something more generic?

Possible, but then I still need to make my own ToString() function,
which is what I wanted to avoid. The point is, I have a very simple
class, but with quite a large number of variables (about 22). So I like
to have an array containing all those variables, so that I can easily
iterate over that array when I want to use the variables.

ViRi's solution does not seem to work, "foreach statement cannot operate
on variables of type 'SMOBY.ServiceOrder'because 'SMOBY.ServiceOrder'
does not contain a public definition for 'GetEnumerator'"
 
K

Kevin Spencer

Implement a ToString() overload for "SomeType" and use it.

--
HTH,

Kevin Spencer
Microsoft MVP
..Net Developer
You can lead a fish to a bicycle,
but you can't make it stink.
 
C

Chris

Daan said:
Possible, but then I still need to make my own ToString() function,
which is what I wanted to avoid. The point is, I have a very simple
class, but with quite a large number of variables (about 22). So I like
to have an array containing all those variables, so that I can easily
iterate over that array when I want to use the variables.

ViRi's solution does not seem to work, "foreach statement cannot operate
on variables of type 'SMOBY.ServiceOrder'because 'SMOBY.ServiceOrder'
does not contain a public definition for 'GetEnumerator'"

Can you store the variables in the class as an array? That may simplify
the issue. Otherwise override the tostring method, use reflection to
find all the properties of the class and do a loop in there to create
your string.

Chris
 
J

Joshua Flanagan

I would recommend using a custom ToString() override, as the other posts
suggested.
But since you asked for a reflection solution and said you couldn't
figure it out, I'll give you an example. This is just to show you how to
do it - this isn't the solution I would recommend in most cases (but
maybe it fits for your scenario).


public class SomeClass
{
public string var1 = "theVar1";
public int var2 = 42;
public DateTime var3 = DateTime.Now;

public object[] GetAllVariablesAsArray()
{
FieldInfo[] fields =
this.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public |
BindingFlags.DeclaredOnly);
// Note - use PropertyInfo and GetProperties() if your values are stored
in properties instead of fields
object[] variables = new object[fields.Length];
for (int i = 0; i < fields.Length; i++)
{
variables = fields.GetValue(this);
}
return variables;
}
}


An example of using the method would be:

class Program
{
static void Main(string[] args)
{
SomeClass sc = new SomeClass();
foreach (object var in sc.GetAllVariablesAsArray())
{
Console.WriteLine(var.ToString());
}
}
}

Hope this helps.

Joshua Flanagan
http://flimflan.com/blog
 
J

Jon Skeet [C# MVP]

ViRi said:
foreach (object o in SomeClass)
{
myPrintFunction(o);
}

think something like this should work.

No, that wouldn't compile - foreach doesn't work on a type name.
 
D

Daan

Joshua said:
But since you asked for a reflection solution and said you couldn't
figure it out, I'll give you an example. This is just to show you how to
do it - this isn't the solution I would recommend in most cases (but
maybe it fits for your scenario).

FieldInfo[] fields =
this.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public |
BindingFlags.DeclaredOnly);
// Note - use PropertyInfo and GetProperties() if your values are stored
in properties instead of fields
object[] variables = new object[fields.Length];
for (int i = 0; i < fields.Length; i++)
{
variables = fields.GetValue(this);
}
return variables;


Thanks Joshua, this is what I was looking for. But I wonder why you say
you would not recommend this solution, is there any risk or uglyness
about this solution?

Daan
 
J

Joshua Flanagan

Thanks Joshua, this is what I was looking for. But I wonder why you say
you would not recommend this solution, is there any risk or uglyness
about this solution?

1) It is slower to evaluate variables through reflection, rather than
referencing the variable directly. It depends on your situation if the
speed difference matters.

2) I would say it is ugly, since reflection is a type of "cheat". It
doesn't use any of the language's built in constructs and concepts. If
you're variables were designed to be used as individual values, then
treat them as individual values. If they are just values in a
colleciton, then use a collection (array) instead of individual
variables. Again, "uglyness" is in the eye of the beholder - if it
doesn't bother you, go for it.

3) Note that in my solution, you do not know in what order the variable
values will come back in. Do not assume that they will always return in
the same order - you will have to do your own sorting if it matters.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top