Looping through Object Properties

T

Trey Balut

I have two classes and I want to loop through the properties and assign them
for later serialization.

public class MyFirstObject
{

public string Name(get;set;}
public int Age{get;set;}
public string City {get;set;}

}


public class MySecondObject
{

public string Name1{get;set;}
public int Age1{get;set;}
public string City1{get;set;}

}

Type myFirstObjectType = typeof(MyFirstObject);

Type mySecondObjectType = typeof(MySecondObject);

System.Reflection.FieldInfo[] fieldInfo1=myFirstObjectType.GetFields();
System.Reflection.FieldInfo[] fieldInfo2=mySecondObjectType.GetFields();



//Now I want to assign them using their indexes

MyFirstObject mfo= new MyFirstObject();


for(int I=0;I<fieldInfo1.Length;I++){

mfo.fieldInfo1[0]=MySecondObject.fieldInfo2[0];
mfo.fieldInfo1[1]=MySecondObject.fieldInfo2[1];

}

Am I missing a cast? Or is it something else?

Thanks.
 
P

Peter Duniho

Trey said:
I have two classes and I want to loop through the properties and assign
them for later serialization.

[...]
Type myFirstObjectType = typeof(MyFirstObject);

Type mySecondObjectType = typeof(MySecondObject);

System.Reflection.FieldInfo[] fieldInfo1=myFirstObjectType.GetFields();
System.Reflection.FieldInfo[] fieldInfo2=mySecondObjectType.GetFields();

//Now I want to assign them using their indexes

MyFirstObject mfo= new MyFirstObject();

for(int I=0;I<fieldInfo1.Length;I++){

mfo.fieldInfo1[0]=MySecondObject.fieldInfo2[0];
mfo.fieldInfo1[1]=MySecondObject.fieldInfo2[1];

}

Am I missing a cast? Or is it something else?

There's lots you're missing. Where to start? :)

First: in the loop above, what's "MySecondObject" supposed to be? Not
that it would work in any case, but "MySecondObject" is the name of a
type while "mfo" is the name of a variable. It's not clear what it is
you expected to happen, nor what it is you're really trying to copy.

Second: you have a loop with index "I", but you never use "I" in the
loop. What's the point of that?

Third: you seem to be assuming that the FieldInfo instances in the array
returned by GetFields() will be in some specific order. Reflection
provides no guarantees about in what order fields are returned.

Fourth: the types you've posted have only properties. The GetFields()
method will return an empty array, because there are no public fields in
the classes.

Fifth: assuming you are trying to copy _values_ from one instance to
another, once you retrieve the necessary FieldInfo or PropertyInfo
instances, it is necessary to use those objects themselves for
manipulating the data. The "MyFirstObject" class doesn't have a
"fieldInfo1" instance member, nor does the "MySecondObject" class have a
"fieldInfo2" static member, both of which would be required for the
syntax you've posted to work.

On that above assumption, here is some code that would accomplish that
specific goal:

class Class1
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}

class Class2
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}

class Class3
{
void CopyProperties(Class1 class1, Class2 class2)
{
foreach (PropertyInfo piSrc in typeof(Class1).GetProperties())
{
PropertyInfo piDst = typeof(Class2).GetProperty(piSrc.Name);

piDst.SetValue(class2, piDst.GetValue(class1, null), null);
}
}
}

Note that this will work only if the property names are _exactly_ the
same. If they are not (as in your original example), you will need to
come up with some specific mapping from one property name to another.
You cannot rely on the ordering of properties, fields, or other members
of classes when retrieving them via reflection.

What any of this has to do with serialization, I have no idea. The fact
is, normally serialization involves just a single type, serialized to
some kind of data storage, and the deserialized back to the original type.

IMHO, the basic idea of using reflection to copy values from an instance
of one type to an instance of a completely different type is fraught
with problems, and for it to work would typically rely on so much
explicit information in the code regarding the relationship between the
two types that you might as well just write a non-reflective copy
method. I suppose there may be situations in which code like the above
is warranted, but it seems to me you should think very carefully before
following this approach whether the benefits outweigh the costs.

Pete
 
T

Trey Balut

Peter,

Many thanks for the solution, and as importantly, sharing your insight re:
the problem.

In my scenario, I am trying to copy (synchronize) a number of tables from a
SqlCE database to a SQL Server database. The tables are all represented by
classes and the fields are properties of the classes.

I wanted to have a general purpose function that would except the source and
destination tables as objects and copy the data.

Your code looks like it will work. I sorta understand the problems with my
approach. But without adding more complexity, like the Synch Framework, I
thought this would be a simple, straitforward solution.

Thanks again.



Peter Duniho said:
Trey said:
I have two classes and I want to loop through the properties and assign
them for later serialization.

[...]
Type myFirstObjectType = typeof(MyFirstObject);

Type mySecondObjectType = typeof(MySecondObject);

System.Reflection.FieldInfo[] fieldInfo1=myFirstObjectType.GetFields();
System.Reflection.FieldInfo[] fieldInfo2=mySecondObjectType.GetFields();

//Now I want to assign them using their indexes

MyFirstObject mfo= new MyFirstObject();

for(int I=0;I<fieldInfo1.Length;I++){

mfo.fieldInfo1[0]=MySecondObject.fieldInfo2[0];
mfo.fieldInfo1[1]=MySecondObject.fieldInfo2[1];

}

Am I missing a cast? Or is it something else?

There's lots you're missing. Where to start? :)

First: in the loop above, what's "MySecondObject" supposed to be? Not
that it would work in any case, but "MySecondObject" is the name of a type
while "mfo" is the name of a variable. It's not clear what it is you
expected to happen, nor what it is you're really trying to copy.

Second: you have a loop with index "I", but you never use "I" in the loop.
What's the point of that?

Third: you seem to be assuming that the FieldInfo instances in the array
returned by GetFields() will be in some specific order. Reflection
provides no guarantees about in what order fields are returned.

Fourth: the types you've posted have only properties. The GetFields()
method will return an empty array, because there are no public fields in
the classes.

Fifth: assuming you are trying to copy _values_ from one instance to
another, once you retrieve the necessary FieldInfo or PropertyInfo
instances, it is necessary to use those objects themselves for
manipulating the data. The "MyFirstObject" class doesn't have a
"fieldInfo1" instance member, nor does the "MySecondObject" class have a
"fieldInfo2" static member, both of which would be required for the syntax
you've posted to work.

On that above assumption, here is some code that would accomplish that
specific goal:

class Class1
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}

class Class2
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}

class Class3
{
void CopyProperties(Class1 class1, Class2 class2)
{
foreach (PropertyInfo piSrc in typeof(Class1).GetProperties())
{
PropertyInfo piDst = typeof(Class2).GetProperty(piSrc.Name);

piDst.SetValue(class2, piDst.GetValue(class1, null), null);
}
}
}

Note that this will work only if the property names are _exactly_ the
same. If they are not (as in your original example), you will need to
come up with some specific mapping from one property name to another. You
cannot rely on the ordering of properties, fields, or other members of
classes when retrieving them via reflection.

What any of this has to do with serialization, I have no idea. The fact
is, normally serialization involves just a single type, serialized to some
kind of data storage, and the deserialized back to the original type.

IMHO, the basic idea of using reflection to copy values from an instance
of one type to an instance of a completely different type is fraught with
problems, and for it to work would typically rely on so much explicit
information in the code regarding the relationship between the two types
that you might as well just write a non-reflective copy method. I suppose
there may be situations in which code like the above is warranted, but it
seems to me you should think very carefully before following this approach
whether the benefits outweigh the costs.

Pete
 

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