views:

71

answers:

2

Like this:

    public class remoteStatusCounts : RemoteStatus 
{
    public int statusCount;

    public remoteStatusCounts(RemoteStatus r)
    {
        Type t = r.GetType();
        foreach (PropertyInfo p in t.GetProperties())
        {
            this.property(p) = p.GetValue(); //example pseudocode
        }
    }
}

The example is a bit simple (it's from the Jira API - RemoteStatus has 4 properties), but imagine the base class had 30 properties. I don't want to manually set all those values, especially if my inherited class only has a couple of extra properties.

Reflection seems to hint at an answer.

I saw at http://stackoverflow.com/questions/3072249/using-inheritance-in-constructor-publix-x-y that I can call the base class constructor (I think? correct me if I'm wrong), but my base class doesn't have a constructor - it's derived from the jira wsdl

        public remoteStatusCounts(RemoteStatus r) : base(r) { //do stuff }

edit I can imagine 2 valid solutions: the one outlined above, and some sort of keyword like this.baseClass that is of type(baseclass) and manipulated as such, acting as a sort of pointer to this. So, this.baseClass.name = "Johnny" would be the exact same thing as this.name = "Johnny"

For all intents and purposes, let's assume the baseclass has a copy constructor - that is, this is valid code:

        public remoteStatusCounts(RemoteStatus r) {
            RemoteStatus mBase = r;
            //do work
        }

edit2 This question is more of a thought exercise than a practial one - for my purposes, I could've just as easily done this: (assuming my "baseclass" can make copies)

    public class remoteStatusCounts 
{
    public int statusCount;
    public RemoteStatus rStatus;
    public remoteStatusCounts(RemoteStatus r)
    {
        rStatus = r;
        statusCount = getStatusCount();
    }
}
+1  A: 

Yes, you can do this - be aware though, that you might run into getter-only properties which you have to deal with seperately.

You can filter it with the Type.GetProperties(BindingsFlags) overload.

Note: You probably should look into code generation (T4 would be an idea, as it is delivered with vs 2008/2010), because reflection could have runtime-implications like execution speed. With codegeneration, you can easily handle this tedious work and still have the same runtime etc like typing it down manually.

Example:

//extension method somewhere
public static T Cast<T>(this object o)
{
    return (T)o;
}

public remoteStatusCounts(RemoteStatus r)
{
    Type typeR = r.GetType();
    Type typeThis = this.GetType();

    foreach (PropertyInfo p in typeR.GetProperties())
    {
        PropertyInfo thisProperty = typeThis.GetProperty(p.Name);

        MethodInfo castMethod = typeof(ExMethods).GetMethod("Cast").MakeGenericMethod(p.PropertyType);
        var castedObject = castMethod.Invoke(null, new object[] { p.GetValue(r, null) });
        thisProperty.SetValue(this, castedObject, null);
    }
}
Femaref
How? I can't call setValue on objects.. this.setValue(p.Name,r.getValue) doesn't compile.
scaryman
You of course have to get the Type object for this, get the corresponding property with t.GetProperty(name) and do the SetValue on that object.
Femaref
It compiles like this: thisProperty.SetValue(this, p.GetValue(typeR,null),null);But then it throws a runtime exception "Object does not match target type"
scaryman
Nope. Can't call getType() on static classes. +1 for getting closer.
scaryman
typeof should fix that
Femaref
Runtime exception - "TargetException was unhandled by user code - Object does not match target type." Thanks for working on this - I really don't know anything about reflection. I figured it should be possible, I really have no idea though.
scaryman
fixed. tested it, this should work. the p.GetValue was wrong - It tried to get the value on the type object, which obviously will fail.
Femaref
Shabam. You're a rockstar.
scaryman
http://stackoverflow.com/questions/1198886/c-using-reflection-to-copy-base-class-properties - this question is similar.
scaryman
+2  A: 

Try AutoMapper.

Jordão
Sweet! I've never heard of that before - that will definitely come in handy sometime!
scaryman