Introduction
This is a simple solution for a simple problem. There will not be any code attachments for this reason. Copy and paste and you're good to go :) On the same note, I will try not just copy and paste code here and hit the big green button. So bare with me just a tiny bit.
Basically...
.NET allows you to cast from an instance of a class of type T
to its base class F
with ease.
Example
Given the classes Male
: Person
: Animal
:
class Animal
{
private int _age;
public int Age
{
get { return this._age; }
set { this._age = value; }
}
}
class Person: Animal
{
private string _codeProjectName;
public string CodeProjectName
{
get { return this._codeProjectName; }
set { this._codeProjectName = value; }
}
}
class Male: Person
{
private long _ego;
public long Ego
{
get { return this._ego; }
set { this._ego = value; }
}
}
We can simply cast a Male
object to a Person
or Animal
, like so:
...
Person yang = new Person();
Animal AlsoYang = (Animal)yang;
...
Problem...
Time to time again, I've always had to deal with the problem of wanting to create an instance of a class of type T
derived from an instance of its base class type F
. (I am implying that I want to copy the Data Model, specifically properties.) Usually, I will simply create a custom constructor or write some hard-coded logic to implement this functionality.
So to do this, we will use Generics, and Reflection.
Like so...
public static T Construct<F, T>(F Base) where T : F, new()
{
T derived = new T();
PropertyInfo[] properties = typeof(F).GetProperties();
foreach (PropertyInfo bp in properties)
{
PropertyInfo dp = typeof(T).GetProperty(bp.Name, bp.PropertyType);
if (
(dp != null)
&& (dp.GetSetMethod() != null)
&& (bp.GetIndexParameters().Length == 0)
&& (dp.GetIndexParameters().Length == 0)
)
dp.SetValue(derived, dp.GetValue(Base,null), null);
}
return derived;
}
Notice that the generic type clause states that T: F
, which means that T
must be a subclass of F
and contains all of the public and private properties of F
. (Again, this implementation deals with properties. If you want variables, be my guest.)
Note: In the above code, we are not cloning the property values, so changing the value of the derived instance will change the base instance since they are from the same pointer.
Using the darn thing...
Using the above example, we can get a new instance of a derived class of Animal
such as a Person
.
...
Animal yang_ox = new Animal();
yang_ox.Age = 10;
Person yang = Construct<Animal, Person>(yang_ox);
...
Further thinking...
Using this approach, one can also address a similar solution for Cloning<T>()
, and even Construct<F,T>
where F:T
.
One could also go even further with this and do some assembly injection compiled code at run time to save all this Reflection jazz.
Hope you enjoyed the short read. Hopefully I won't get any 1s. Fingers are crossed. ^_^