Есть ли способ использовать разные конструкторы в зависимости от начального значения enum? - PullRequest
2 голосов
/ 23 февраля 2020

В настоящее время я работаю над созданием игры dungeon-crawler-esque в c#, но в настоящее время у меня возникают проблемы с конструкторами класса. Мне было интересно, возможно ли иметь разные конструкторы в зависимости от начального значения enum? В этом случае у него есть только два возможных значения, поэтому достаточно простого логического значения, но если бы у меня было больше двух, мне было бы интересно, если бы вы могли выполнять разные конструкторы в зависимости от введенного начального значения перечисления? Извините, если мое форматирование неверно или я не очень точно указал c, я впервые задаю вопрос здесь:)).

Для справки здесь приведены мои текущие перечисления здесь:

public enum Type
{
    Passive,
    Action
}

public enum Trigger
{
    PlayerTakeDamage,
    EnemyTakeDamage,
    Draw,
    PlayerDebuff,
    EnemyDebuff,
    PlayCard
}

Вот что я хочу сделать sh:

public class Action
{
    public int Energy {get; private set;}
    public int Damage {get; private set;}

    public Action(Type.Passive, Trigger trigger, int damage, int energy)
    {
        do thing;
    }
    public Action(Type.Action, int damage, int energy)
    {
        do other thing;
    }
}

Опять же, я прошу прощения, если это глупый вопрос или я испортил форматирование здесь, но я был бы искренне признателен за любые советы или рекомендации, которые кто-либо мог бы предложить:))!

Редактировать: Извините, я не особо уточнил c о потенциальных приложениях. Я хочу перегрузить конструкторы, основываясь на начальном значении enum, потому что я хочу заполнить другие дополнительные параметры после того, как это потребуется при создании. Я добавил пояснения, чтобы помочь:)).

Ответы [ 3 ]

1 голос
/ 23 февраля 2020

Нечто подобное может быть тем, что вы ищете в концепции.

public class Person
{
    private int _Speed;
    private double _ReactionTime;
    private int _CalorieConsumptionPerHour;

    public Person(Stance stance) 
    {
        if (stance == Stance.Active)
            setToActive();
        else if (stance == Stance.Passive)
            setToPassive();
        else
            setToDefault();
    }

    private void setToActive()
    {
        _Speed = 30;
        _ReactionTime = .15;
        _CalorieConsumptionPerHour = 200;
    }

    private void setToPassive()
    {
        _Speed = 10;
        _ReactionTime = .5;
        _CalorieConsumptionPerHour = 100;
    }

    private void setToDefault()
    {
        _Speed = 20;
        _ReactionTime = .3;
        _CalorieConsumptionPerHour = 150;
    }

    public enum Stance
    {
        Active,
        Passive
    }
}
1 голос
/ 23 февраля 2020

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

Я бы вообще использовал другой подход. Когда-либо слышали о Io C (инверсия контроля) Что такое инверсия контроля?

Модели инверсии контроля (Io C) и внедрения зависимостей (DI) все об удалении зависимостей из вашего кода.

Что это значит в вашем случае?

Предположим, что существуют разные типы действий, все придерживающиеся тех же правил (одинаковые методы).

Это крики Interface на OOP языках

public Interface IAction {
    void DoSomething();
    int DoSomethingElse();
}

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

public abstract AbstractAction: IAction {
    public int Energy {get; private set;}
    public int Damage {get; private set;}
}

Теперь создайте разные классы для каждого действия

public class PlayerTakeDamageAction: AbstractAction {

    public PlayerTakeDamageAction(/*some parameters*/) {
    }

    // Override the behavior per class
}

Какое отношение все это имеет к вам? Теперь вы можете применить IoC, используя Dependency Injection или FactoryPattern. Это означает, что вы делегируете создание объекта IAction кому-либо еще.

Вот тривиальный пример абстрактной фабрики

public class ActionConsumer {
    private IActionFactory factory;

    public A(IActionFactory factory) {
        this.factory = factory;
    }

    public void DoSomething() {
        IAction a = factory.MakeAction(Trigger.PlayerTakeDamageAction);
        a.DoSomething();
    }
}

public ConcreteActionFactory: IActionFactory {
    IAction MakeAction() {
        return new PlayerTakeDamageAction();
    }

    IAction MakeAction(Trigger trigger) {
        if (Trigger == Trigger.PlayerTakeDamageAction)
           return new PlayerTakeDamageAction();
        else if // you get the idea
    }
}

interface IActionFactory {
    // Creates some default action
    IAction MakeAction();
    // Creates some specific action
    // You can pass any parameters or create multiple action
    // generators, depending on what the new object needs.
    IAction MakeAction(Trigger trigger);
}
1 голос
/ 23 февраля 2020

У нас может быть перегрузка конструктора с другой подписью. Перегрузка конструктора выполняется количеством параметров, различными типами параметров, но не значением. Я упростил ваш код с помощью условия, надеюсь, это поможет.

public class Action
{
    public Action(Type t)
    {  
        if(t == Type.Passive)
        { 
            //do thing; 
        }
        else if(t== Type.Action)
        { 
            //do another thing; 
        }
    }
}
...