От одного и того же класса наследуются несколько других с дополнительными свойствами. Хочу написать универсальную функцию, которая бы работала со списками объектов этих новых классов, т.е. на вход список и параметр, а на выходе элемент списка. Вот упрощенный код того, что примерное хочу реализовать (функция FindByName):
class Animal
{
public string Name;
}
class Dog:Animal
{
//some other properties and methods
}
class Cat:Animal
{
//some other properties and methods
}
class Program
{
static dynamic FindByName(dynamic list, string name)
{
return list.Find(x => x.Name == name);
}
static void Main(string[] args)
{
List<Dog> dogs = GetListOfDogs();
//List<Cat> cats = GetListOfCats();
Dog DogTuzik = FindByName(dogs, "Tuzik");
//Cat Murka = FindByName(cats, "Murka");
}
static List<Dog> GetListOfDogs()
{
List<Dog> dogs = new List<Dog>();
dogs.Add(new Dog{Name="Tuzik"});
dogs.Add(new Dog{Name="Sharik"});
return dogs;
}
}
Компилятор, естественно, ругается:
"Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type."
На самом деле FindByName гораздо объёмнее, чем в примере, поэтому и хочу убрать его в отдельную процедуру, чтобы сделать код более читаемым.
Поэтому вопрос, как сделать это правильно и может быть более изящно?
Вообще это решается примерно так:
static T FindByName<T>(IEnumerable<T> list, string name) where T : Animal
{
return list.FirstOrDefault(x => x.Name == name);
}
Зы. Использовать dynamic в C# очень редко требуется, в основном при взаимодействии с какими-то внешними динамически типизированными языками/средами
Можно оставить и dynamic но немного переделать метод в такой:
static dynamic FindByName<T>(dynamic list, string name) where T : Animal
{
return list is List<T> animals ? animals.Find(x => x.Name == name) : null;
}
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости