vendredi 2 juillet 2021

C# Pass DataMembers to expression body using reflection

I have some models that I save into XML which look like this:

public class Point
{
    [DataMember(Name = nameof(Name))]
    public string Name { get; set; }

    [DataMember(Name = nameof(X))]
    public double X { get; set; }

    [DataMember(Name = nameof(Y))]
    public double Y { get; set; }

    and so on...
}

These models have a SaveToXml and a LoadFromXml method:

public virtual XElement SaveToXml(XElement obj)
{
    this.SaveToObject(s => s.Name, obj);
    this.SaveToObject(s => s.X, obj);
    this.SaveToObject(s => s.Y, obj);

    return obj;
}

public virtual void LoadFromXml(XElement obj)
{
    this.LoadFromObject(s => s.Name, obj);
    this.LoadFromObject(s => s.X, obj);
    this.LoadFromObject(s => s.Y, obj);
} 

The SaveToObject and LoadFromObject methods are extension methods of XElement which get/set the value of the passed DataMember (Name, X, Y, etc.) from the XElement obj passed.

My problem is that these models tend to get pretty big and every added/removed member needs a change in the SaveToXml and LoadFromXml methods. So I have been trying to find a way to get all DataMembers of my model using reflection and try passing those for the Save/Load methods, but I am doing something wrong.

This is what I came up with so far:

var props = typeof(Point).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(DataMemberAttribute)));

foreach (var prop in props)
{
    this.TrySave(prop.GetValue(this), element);
}

This does not cause an error for the save (it asks for a reference type in the Load method), but it does not save the values nor throws an exception.





Aucun commentaire:

Enregistrer un commentaire