Reflection question (for <= .NET 3.5)
-
Hey guys, Long story short: I have a number of classes that are structured like this:
class ClassA
{
[WantToCopy]
public Property1 { get; set; }
public Property2 { get; set; } // ...
}class ClassB : ClassA
{
public Property1 { get; set; }
public Property2 { get; set; } // ...
}class ClassC
{
public ClassB { get; set; }
public Property1 { get; set; }
public Property2 { get; set; } // ...
}I am trying copy the ClassA values (marked with a specific attribute) from an instance of ClassB to a new instance of ClassA. This is what I am doing:
T resp = GetClassC(); // get a pretend instance of ClassC
var types = resp.GetType().GetProperties();
foreach (var type in types)
{
// I use this to figure out if the field in ClassC == ClassB
if(type.PropertyType.IsSubclassOf(this.GetType()))
{
// I use this custom method to get the properties in ClassA that have the
// attribute mentioned above
List fields = GetFields(type.PropertyType);
foreach (var field in fields)
{
// here is the problem!
var value = field.GetValue(resp , null); // resp is ClassC
field.SetValue(this, value , null); // 'this' is ClassA
}
}
}The problem is I get a TargetException when I try and get a ClassA value from a ClassC instance (which makes sense). ClassC is a generic type. I don't know anything about the ClassB member. Does anyone have any tricks that could help me out here? Or will I have to use an interface? P.S I am keen to keep this code to <= .NET 3.5 if possible. Thank you, Mark
Mark Brock "We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen
-
Hey guys, Long story short: I have a number of classes that are structured like this:
class ClassA
{
[WantToCopy]
public Property1 { get; set; }
public Property2 { get; set; } // ...
}class ClassB : ClassA
{
public Property1 { get; set; }
public Property2 { get; set; } // ...
}class ClassC
{
public ClassB { get; set; }
public Property1 { get; set; }
public Property2 { get; set; } // ...
}I am trying copy the ClassA values (marked with a specific attribute) from an instance of ClassB to a new instance of ClassA. This is what I am doing:
T resp = GetClassC(); // get a pretend instance of ClassC
var types = resp.GetType().GetProperties();
foreach (var type in types)
{
// I use this to figure out if the field in ClassC == ClassB
if(type.PropertyType.IsSubclassOf(this.GetType()))
{
// I use this custom method to get the properties in ClassA that have the
// attribute mentioned above
List fields = GetFields(type.PropertyType);
foreach (var field in fields)
{
// here is the problem!
var value = field.GetValue(resp , null); // resp is ClassC
field.SetValue(this, value , null); // 'this' is ClassA
}
}
}The problem is I get a TargetException when I try and get a ClassA value from a ClassC instance (which makes sense). ClassC is a generic type. I don't know anything about the ClassB member. Does anyone have any tricks that could help me out here? Or will I have to use an interface? P.S I am keen to keep this code to <= .NET 3.5 if possible. Thank you, Mark
Mark Brock "We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen
You're trying to read the value of a property defined in
ClassA
from an instance ofClassC
, which doesn't inherit fromClassA
. Try something like this instead:// This is an expensive call; cache the result:
Type myType = this.GetType();// No need to examine sub-classes; if a property isn't
// defined on this class, you won't be able to copy it:
List propertiesToCopy = GetFields(myType);foreach (PropertyInfo property in resp.GetType().GetProperties())
{
// IsSubclassOf returns false if the types are the same:
if (property.PropertyType.IsSubclassOf(myType) || property.PropertyType == myType)
{
// Get the instance of ClassB:
var propertyValue = property.GetValue(resp, null);// Can't copy properties from a null instance: if (propertyValue == null) continue; foreach (PropertyInfo propertyToCopy in propertiesToCopy) { var value = propertyToCopy.GetValue(propertyValue, null); propertyToCopy.SetValue(this, value, null); } }
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
Hey guys, Long story short: I have a number of classes that are structured like this:
class ClassA
{
[WantToCopy]
public Property1 { get; set; }
public Property2 { get; set; } // ...
}class ClassB : ClassA
{
public Property1 { get; set; }
public Property2 { get; set; } // ...
}class ClassC
{
public ClassB { get; set; }
public Property1 { get; set; }
public Property2 { get; set; } // ...
}I am trying copy the ClassA values (marked with a specific attribute) from an instance of ClassB to a new instance of ClassA. This is what I am doing:
T resp = GetClassC(); // get a pretend instance of ClassC
var types = resp.GetType().GetProperties();
foreach (var type in types)
{
// I use this to figure out if the field in ClassC == ClassB
if(type.PropertyType.IsSubclassOf(this.GetType()))
{
// I use this custom method to get the properties in ClassA that have the
// attribute mentioned above
List fields = GetFields(type.PropertyType);
foreach (var field in fields)
{
// here is the problem!
var value = field.GetValue(resp , null); // resp is ClassC
field.SetValue(this, value , null); // 'this' is ClassA
}
}
}The problem is I get a TargetException when I try and get a ClassA value from a ClassC instance (which makes sense). ClassC is a generic type. I don't know anything about the ClassB member. Does anyone have any tricks that could help me out here? Or will I have to use an interface? P.S I am keen to keep this code to <= .NET 3.5 if possible. Thank you, Mark
Mark Brock "We're definitely not going to make a G or a PG version of this. It's not PillowfightCraft." -- Chris Metzen
As you seem to have access to the code, why not add a copy constructor or Clone method to ClassA?
-
You're trying to read the value of a property defined in
ClassA
from an instance ofClassC
, which doesn't inherit fromClassA
. Try something like this instead:// This is an expensive call; cache the result:
Type myType = this.GetType();// No need to examine sub-classes; if a property isn't
// defined on this class, you won't be able to copy it:
List propertiesToCopy = GetFields(myType);foreach (PropertyInfo property in resp.GetType().GetProperties())
{
// IsSubclassOf returns false if the types are the same:
if (property.PropertyType.IsSubclassOf(myType) || property.PropertyType == myType)
{
// Get the instance of ClassB:
var propertyValue = property.GetValue(resp, null);// Can't copy properties from a null instance: if (propertyValue == null) continue; foreach (PropertyInfo propertyToCopy in propertiesToCopy) { var value = propertyToCopy.GetValue(propertyValue, null); propertyToCopy.SetValue(this, value, null); } }
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
As you seem to have access to the code, why not add a copy constructor or Clone method to ClassA?