3

Is it possible to retrieve the value of an attribute applied to an instance of a class from within that class? An example of this would be:

class Host {
    [XmlElement("NAME")]
    public ChildClass c { get; set; }
}

[Serializable()]
class ChildClass : IXmlSerializable {
    ...
    void IXmlSerializable.WriteXml(XmlWriter writer) {
        OtherClass desiredElement = ...
        string desiredElementName = ???
        XmlSerializer = new XmlSerializer(desiredElement.GetType(), new XmlRootAttribute(desiredElementName));
        serializer.Serialize(writer, desiredElment);
    }
}

Where desiredElementName should contain NAME?

CoryG
  • 2,429
  • 3
  • 25
  • 60
  • You can use reflection to get the properties that have the desired attribute and then extract the information as needed. – Nkosi Jan 11 '18 at 17:15
  • 1
    @Nkosi How do I do that specifically for the attributes applied to a particular instance of a class definition without knowing anything about `Host` - only code within `ChildClass`? – CoryG Jan 11 '18 at 17:17
  • Oh ok. no. I mis-read the requirements then. – Nkosi Jan 11 '18 at 17:17

1 Answers1

2

This cannot be done directly, you'll have to pass a reference of the parent to the child. If this isn't a problem then it is possible:

public class Host {
    public Host()
    {
        c = new ChildClass(this);
    }

    [XmlElement("NAME")]
    public ChildClass c { get; set; }
}

[Serializable()]
public class ChildClass : IXmlSerializable {
    private object _parent { get; }

    public ChildClass(object parent)
    {
        _parent = parent;
    }

    public void IXmlSerializable.WriteXml(XmlWriter writer) {

        var props = _parent.GetType().GetProperties();
        var propElement = props.Where(p => p.PropertyType == GetType()).FirstOrDefault();
        var desiredElementName = propElement.CustomAttributes.FirstOrDefault(p => p.AttributeType == typeof(XmlElementAttribute))?.ConstructorArguments.FirstOrDefault()?.Value;

        var desiredElement = _parent;

        XmlSerializer = new XmlSerializer(desiredElement.GetType(), new XmlRootAttribute(desiredElementName));
        serializer.Serialize(writer, desiredElment);
    }
}

Though I'm not sure if desiredElement contains the object you had in mind.

Please note: I tested this with .net core 2.0. I don't know if there are changes in reflection.