简体   繁体   中英

Deferred type inference for inherited class method

What I'm trying to do, without success, is a method on a base class that, using reflection, would update properties defined into inherited classes. So, starting from a specific method like this

/** fill the item from a xml node
 */
public TblItem FromXML (XmlNode itemNode)
{
    foreach (XmlNode itemField in itemNode) {
        Type myType = this.GetType ();
        PropertyInfo myPropInfo = myType.GetProperty (itemField.Name);
        if (myPropInfo != null) {
            myPropInfo.SetValue (this, Convert.ChangeType (itemField.InnerText, myPropInfo.PropertyType), null);
        } else {            
            throw new MissingFieldException (string.Format ("[Fieldname]wrong fieldname: {0}", itemField.Name));
        }
    }
    return this;
}

I need it to be defined in a base class called ie TblBase , containing no properties at all, and being used seamlessly in all the derived classes, ie TblDerived1: TblBase etc. in which there are different properties defined for each of them, so I'm here asking: is there a way to do that or it is just a dream of my dirty mind? BTW, this is how I need to use this stuff:

    xmlDoc.Load (XMLDbPath); 
    XmlNodeList itemNodes = xmlDoc.SelectNodes (nodes2select);
    //Tblitem inherits TblBase
    TblItem ti = new TblItem ();
    foreach (XmlNode itemNode in itemNodes) {
        print (((TblItem)ti).FromXML (itemNode).ToString ());
    }

See code using generics below, I replaced the xml node with a name and a value so I could test.

  public T FromXML<T>(string name, string value) where T: TblBase
            {
                Type myType = this.GetType();
                PropertyInfo myPropInfo = myType.GetProperty(name);
                if (myPropInfo != null)
                {
                    myPropInfo.SetValue(this, Convert.ChangeType(value, myPropInfo.PropertyType), null);
                }
                else
                {
                    throw new MissingFieldException(string.Format("[Fieldname]wrong fieldname: {0}", name));
                }
                return (T)this;
            }

And calling it: var result = yourItem.FromXML(someName, someValue);

But, it will work without generics as well:

    public TblBase FromXML (XmlNode itemNode)
{
    foreach (XmlNode itemField in itemNode) {
        Type myType = this.GetType ();
        PropertyInfo myPropInfo = myType.GetProperty (itemField.Name);
        if (myPropInfo != null) {
            myPropInfo.SetValue (this, Convert.ChangeType (itemField.InnerText, myPropInfo.PropertyType), null);
        } else {            
            throw new MissingFieldException (string.Format ("[Fieldname]wrong fieldname: {0}", itemField.Name));
        }
    }
    return this;
}

and calling it: TblItem result = (TblItem)yourItem.FromXml(...);

Edit:

This will work on properties (with get and set). If you have field data members you want to change in the same way, you need to use GetField instead of GetProperty:

var myFieldInfo = myType.GetField(name)
...
myFieldInfo.SetValue (this, Convert.ChangeType (itemField.InnerText, myFieldInfo.FieldType));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM