Here's my scenario, I've got the following class, and I want to have the constructor deserialize some elements of the class. I would really rather NOT use a factory method here.
public abstract class AccessLevelAgentBase : IAccessLevelAgent
{
public List<AccessLevel> AccessLevels { get; set; }
[XmlElement]
public string PasswordPrompt { get; set; }
[XmlElement]
public string GetAccessLevelKeystroke { get; set; }
开发者_StackOverflow社区 [XmlElement]
public int Doohicky { get; set;}
public AccessLevelAgentBase(XElement agentElement)
{
// Some Mojo Here to take agentElement and serialize
// from the XML below to set the values of PasswordPrompt,
// GetAccessLevelKeystroke, and Doohicky.
}
}
The XML:
<AccessLevelAgent>
<PasswordPrompt> Password ?: </PasswordPrompt>
<PromptCommand>Ctrl+X</PromptCommand>
<Doohicky>50</Doohicky>
</AccessLevelAgent>
simple way...
public AccessLevelAgentBase(XElement agentElement)
{
this.AccessLevels = (string)agentElement.Element("AccessLevels");
this.GetAccessLevelKeystroke = (string)agentElement.Element("GetAccessLevelKeystroke");
this.Doohicky = (int)agentElement.Element("Doohicky");
}
... not so simple way...
public AccessLevelAgentBase(XElement agentElement)
{
var type = this.GetType();
var props = from prop in type.GetProperties()
let attrib = prop.GetCustomAttributes(typeof(XmlElementAttribute), true)
.OfType<XmlElementAttribute>()
.FirstOrDefault()
where attrib != null
let elementName = string.IsNullOrWhiteSpace(attrib.ElementName)
? prop.Name
: attrib.ElementName
let value = agentElement.Element(elementName)
where value != null
select new
{
Property = prop,
Element = value,
};
foreach (var item in props)
{
var propType = item.Property.PropertyType;
if (propType == typeof(string))
item.Property.SetValue(this, (string)item.Element, null);
else if (propType == typeof(int))
item.Property.SetValue(this, (int)item.Element, null);
else
throw new NotSupportedException();
}
}
精彩评论