Определите ограничение общего типа того же типа, что и реализация - PullRequest
0 голосов
/ 23 октября 2018

Интересно, можно ли навязать ограничение универсального типа интерфейса или абстрактного класса так же, как конкретный класс, который реализует его специально для него?

Допустим, мы хотим проверить пригодность определенногосущность к задаче и делает ее сравнимой с другими по их мастерству

abstract class Entity
{
    public abstract int Fitness(); //Bigger the number - more fit the entity is

    public int MoreFitThan(Entity other)
    {
        return Fitness().CompareTo(other.Fitness());
    }
}

class Fish : Entity
{
    public int swimSpeed { get; set; }

    public override int Fitness()
    {
        return swimSpeed;
    }
}

class Human : Entity
{
    public int testPoints { get; set; }

    public override int Fitness()
    {
        return testPoints;
    }
}

Но теперь мы можем сравнить скорость рыбы с способностью человека пройти тест, что не имеет смысла.

static void Main()
        {
            Human human = new Human() {testPoints = 10};
            Fish fish = new Fish() { swimSpeed = 20 };
            fish.MoreFitThan(human);
        }

Так есть ли общий способ создать некоторый класс или интерфейс, который заставил бы его дочерние классы реализовывать только собственный тип для сравнения собственных типов?Например, мы могли сравнивать только людей с людьми и рыбу с рыбой, но без явного указания типа сопоставимой сущности?

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

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

abstract class Entity<T> where T : Entity<T>
{
    public abstract int Fitness(); //Bigger the number - more fit the entity is

    public int MoreFitThan(T other)
    {
        return Fitness().CompareTo(other.Fitness());
    }
}

class Fish : Entity<Fish>
{
    public int swimSpeed { get; set; }

    public override int Fitness()
    {
        return swimSpeed;
    }
}

class Human : Entity<Human>
{
    public int testPoints { get; set; }

    public override int Fitness()
    {
        return testPoints;
    }
}

Тогда следующее будет ошибкой компиляции

Human human = new Human() {testPoints = 10};
Fish fish = new Fish() { swimSpeed = 20 };
fish.MoreFitThan(human);

потому что Human не является Fish.Однако это позволило бы сравнить класс, унаследованный от Fish, с Fish.

class Trout : Fish 
{
    public int size { get; set; }

    public override int Fitness()
    {
        return size;
    }
}

Следующее работает, потому что Trout является Fish.

Trout trout = new Trout() {size = 10};
Fish fish = new Fish() { swimSpeed = 20 };
fish.MoreFitThan(trout);
0 голосов
/ 23 октября 2018

Мое предложение было бы создать классы сопоставимых типов, скажем: Swimmer, Runner, Learner, которые реализуют ваш интерфейс, затем в этих классах также реализуют IComparable и применяют ограничение для этого типа класса.Затем вы можете расширить эти классы с помощью Human для Learner, Fish для Swimmer и т. Д. *

Есть и другие способы сделать это, но это должно работать нормально для ваших нужд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...