В настоящее время я работаю со многими классами и списками этих классов. Ранее у меня были статические методы, которые принимали бы определенный список классов и возвращали подмножество или один элемент списка.
Однако я подумал, что было бы удобнее иметь классы, которые наследуют List и имеют там необходимые методы и больше не делают их статичными, поэтому они применяются к любому списку объектов, которые вы используете.
Мне не удалось найти простой способ преобразовать List в мой класс, который наследует это, поэтому я создал метод во всех этих классах коллекций, чтобы преобразовать его для меня.
Пример:
public class Student
{
public int Id {get;set;}
public string Name {get;set;}
}
public class Students : List<Student>
{
public Student GetTopStudent()
{
return this.OrderByDescending(s => s.Grade).FirstOrDefault();
}
public Students GetPassingStudents()
{
return this.Where(s => s.Grade > 0.7).ToCollection();
}
public Students ToCollection(IEnumerable<Student> studentsList)
{
var students = new Students();
foreach(var s in studentsList)
{
students.Add(s);
}
return students();
]
}
У меня есть много других классов и списков таких классов, но это довольно простой пример. Я обнаружил, что некоторые из моих методов, например метод ToCollection (), практически идентичны между классами, за исключением типа возвращаемого значения и типа, содержащегося в списке.
Итак, я попытался создать расширения и интерфейсы, чтобы автоматически позаботиться об этих методах.
Класс коллекции и интерфейсы
public abstract class Collection<T> : List<T>
{
// Needed tie in the extension method with the List.Add() Method
public void Add(object item) => base.Add((T)item);
}
public interface IObjectWithId<T>
where T : IObjectWithId<T>
{
int Id {get;set;}
}
public ICollectionItem<C>
where C : Collection<IcollectionItem<C>>
{
}
public ICollectionItemWithId<C,T>
where C : Collection<ICollectionItemWithId<C,T>>
where T : IObjectWithId<T>
{
}
Расширения
public static List<T> Get<T>(this IEnumerable<IobjectWithId<T>> list, List<int> ids)
where T : IObjectWithId<T>
{
return list.Where(i => ids.Contains(i.Id))
.Cast<T>();
.ToList();
}
public static C Get<C, T>(this IEnumerable<IcollectionItemWithId<C, T>> list, List<int> ids)
where C : Collection<ICollectionItemWithId<C, T>>, new()
where T : IObjectWithId<T>
{
return list.Where(i => ids.Contains(i.Id)).ToCollection();
}
public static C ToCollection<C, T>(this IEnumerable<ICollectionItemWithId<C, T>> list)
where C : Collection<ICollectionItemWithId<C, T>>, new()
where T : IObjectWithId<T>
{
var collection = new C();
foreach(var item in list)
{
collection.Add(item);
}
return collection;
}
public static C ToCollection<C>(this IEnumerable<ICollectionItem<C>> list)
where C : Collection<ICollectionItem<C>>, new()
{
var collection = new C();
foreach(var item in list)
{
collection.Add(item);
}
return collection;
}
Мне не удалось заставить этот код работать. Обычно я получаю ошибки после его создания, либо нет неявного преобразования ссылок из класса ученика в список учеников, либо ошибка, связанная с боксом.
Я обеспокоен тем, что мои интерфейсы, ссылающиеся друг на друга, могут создавать много проблем, однако причина, по которой я это делаю, заключается в том, что мне не нужно указывать тип возвращаемого значения метода, хотя, возможно, это будет проще всего делать на этом этапе ...