vendredi 5 août 2016

Simplest way to compare object with the result of PropertyInfo.GetValue in C#?

  • C is some class has property members with DisplayNameAttribute
  • GetDisplayName method returns the DisplayNameAttribute parameter of the specified property member

My problem is the implementation is really redundant because method SequenceEqual needs specified type parameters, so I should implement IF code block for each possible property type. Is there any reflection black magic can make my code cleaner? Thank you in advance.

public class C
{
    [DisplayName("M1")]
    public List<string> M1 { get; set; }
    [DisplayName("M2")]
    public List<string> M2 { get; set; }
    [DisplayName("M3")]
    public string M3 { get; set; }
    [DisplayName("M4")]
    public List<int> M4 { get; set; }
    //There can be many property members with different type
    //M5
    //...
    //...
    //M99
}

public void GetCMemberDisplayName()
{
    var c = new C
    {
        M1 = new List<string> {"a"},
        M2 = new List<string>(),
        M3 = "b",
        M4 = new List<int>()
    };
    var nameOfM1 = GetDisplayName(c, c.M1);//"M1"
    var nameOfM2 = GetDisplayName(c, c.M2);//"M2"
    var nameOfM3 = GetDisplayName(c, c.M3);//"M3"
}

private static string GetDisplayName(object instance, object member)
{
    var propertyInfos = instance.GetType()
        .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
                        | BindingFlags.GetField | BindingFlags.GetProperty)
        .FindAll(pi => pi.IsDefined(typeof(DisplayNameAttribute), true));


    foreach (var propertyInfo in propertyInfos)
    {
        var value = propertyInfo.GetValue(instance, null);

        //Very nasty code below, need implement all IF code for each type of property member
        if (member.GetType() == typeof(List<string>) && value.GetType() == typeof(List<string>))
        {
            if ((value as List<string>).SequenceEqual(member as List<string>))
            {
                return (propertyInfo.GetCustomAttributes(true).ToList()
                    .Find(a => (a as DisplayNameAttribute) != null) as DisplayNameAttribute)
                    .DisplayName;
            }
        }
        else if (member.GetType() == typeof(List<int>) && value.GetType() == typeof(List<int>))
        {
            if ((value as List<int>).SequenceEqual(member as List<int>))
            {
                return (propertyInfo.GetCustomAttributes(true).ToList()
                    .Find(a => (a as DisplayNameAttribute) != null) as DisplayNameAttribute)
                    .DisplayName;
            }
        }
        else
        {
            if (value == member)
            {
                return (propertyInfo.GetCustomAttributes(true).ToList()
                    .Find(a => (a as DisplayNameAttribute) != null) as DisplayNameAttribute)
                    .DisplayName;
            }
        }


    }

    throw new Exception("No DisplayNameAttributes Applied.");
}





Aucun commentaire:

Enregistrer un commentaire