Тестирование универсального IComparer

Я пытаюсь сделать общий компаратор, и я не уверен, что происходит не так.

Код компаратора:

namespace Pract_02
{
    public class ComparerProperty<T> : IComparer<T>
    {
        private String attribute;
        public ComparerProperty(String text)
        {
            attribute = text;
        }
        public int Compare(T x, T y)
        {
            PropertyDescriptor property = GetProperty(attribute);
            IComparable propX = (IComparable)property.GetValue(x);
            IComparable propY = (IComparable)property.GetValue(y);
            return propX.CompareTo(propY);

        }

        private PropertyDescriptor GetProperty(string name)
        {
            T item = (T)Activator.CreateInstance(typeof(T));
            PropertyDescriptor propName = null;
            foreach (PropertyDescriptor propDesc in TypeDescriptor.GetProperties(item))
            {
                if (propDesc.Name.Contains(name)) propName = propDesc;
            }
            return propName;
        }
    }
}

И это мой тестовый код:

public void TestComparer()
    {
        SortedSet<Vehicle> list = new SortedSet<Vehicle>(new ComparerProperty<Vehiculo>("NumWheels"));
        Car ca = new Car();
        Moto mo = new Moto();
        Tricycle tri = new Tricycle();
        list.Add(tri);
        list.Add(ca);
        list.Add(mo);
        IEnumerator<Vehiculo> en = list.GetEnumerator();
        en.MoveNext();
        Assert.AreEqual(en.Current, mo);
        en.MoveNext();
        Assert.AreEqual(en.Current, tri);
        en.MoveNext();
        Assert.AreEqual(en.Current, ca);


    }

Проблема в том, что когда я проверяю это, я получаю

"System.MissingMethodException: не удалось создать абстрактный класс."

Вот код для моих классов автомобилей и автомобилей:

public abstract class Vehicle
{
    public abstract int NumWheels
    {
        get;
    }
}

public class Car : Vehicle
{
    public override int NumWheels
    {
        get
        {
            return 4;
        }
    }
}

1 ответ

Решение

MissingMethodException произошла, когда вы пытались создать экземпляр из абстрактного класса Vehicle. Проблема в строке:

T item = (T)Activator.CreateInstance(typeof(T));

Вы можете использовать следующий код для решения проблемы

PropertyDescriptor propName = null;
foreach (PropertyDescriptor propDesc in TypeDescriptor.GetProperties(typeof(T)))
{
    if (propDesc.Name.Contains(name)) propName = propDesc;
}

return propName;

Кстати, у вашего подхода есть еще несколько проблем, например:

  • Если вы попытаетесь сравнить несуществующее свойство, вы получите NullReferenceException
  • Если вы попытаетесь сравнить нулевое свойство, вы получите также NullReferenceException
  • Если свойство не IComparable, вы получаете InvalidCastException
Другие вопросы по тегам