Как СУХОЙ статический повторяющийся шаблонный код в производных классах? - PullRequest
1 голос
/ 10 марта 2019

У меня есть эта модель наследования:

public class Animal
{
}

public class Dog : Animal
{
    public static List<Action<Dog>> Augmenters = new List<Action<Dog>>();
}

public class Cat : Animal
{
    public static List<Action<Cat>> Augmenters = new List<Action<Cat>>();
}

// in another place of the code, augmenters are added and configured
public static void Main (string[] args) 
{
    Dog.Augmenters.Add(dog => 
    {
         // doing something with dog
    });        
    Cat.Augmenters.Add(cat => 
    {
         // doing something with cat
    });
}

Аугментеры содержат много статического кода в каждом Dog / Cat / и т. Д. классы, включая проверку на ноль, создание экземпляров, управление параллелизмом, настройку производительности и т. д., которые одинаковы для всех производных классов.

Аугментаторы для собак должны быть статичными, потому что они применяются ко всем собакам, а не только к одной собаке. Как и кошачьи аугментаторы и т. Д.

Однако их нельзя перенести в класс Animal, поскольку дополнители каждого производного класса отличаются от других классов. Если я перейду Augmenters в класс Animal, то каждый усилитель, который должен принадлежать только кошкам, будет применяться и к собакам.

Как вы СУШИТЕ этот тип стандартного кода?

Я видел нечто похожее для C ++ здесь, оно называется CRTP .

1 Ответ

3 голосов
/ 10 марта 2019

Дайте мне попробовать высохнуть

class Program
{

    public abstract class Animal<T> where T : Animal<T>
    {
        public static List<Action<T>> Augmenters = new List<Action<T>>();
    }

    public class Dog : Animal<Dog>
    {

    }

    public class Cat : Animal<Cat>
    {

    }

    // in another place of the code, augmenters are added and configured
    public static void Main(string[] args)
    {
        Dog.Augmenters.Add(dog =>
        {
            Console.WriteLine("bark");
        });

        Cat.Augmenters.Add(cat =>
        {
            Console.WriteLine("meow");
        });

        Dog.Augmenters[0].Invoke(new Dog());
        Cat.Augmenters[0].Invoke(new Cat());
        Console.ReadLine();
    }
}

Добавлен абстрактный метод и добавлено ограничение для его типа, по крайней мере, вам не нужно повторять реализацию Augementers внутри конкретных классов.

...