Search code examples
c#reflectionattributescomponentmodel

Get c# attribute applied to this instance?


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?


Solution

  • 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.