Enum struct? Объект Value, который ведет себя как Enum - PullRequest
4 голосов
/ 28 ноября 2008

Мне интересно, как бы вы подошли к этой проблеме

У меня есть два Taxrates, которые могут применяться к моим продуктам. Я специально хочу избежать сохранения Taxrates в базе данных, но при этом иметь возможность изменять их в центральном месте (например, Taxrate с 20% до 19% и т. Д.).

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

Я мог бы пойти с Enum, который отображается на значение. Но тогда мне пришлось бы создать какой-нибудь метод, который бы извлекал немецкое имя этого Taxrate для английского enum-значения (я пишу свой код на английском языке, приложение на немецком языке).

Я думал об использовании жестко закодированных объектов, чтобы отразить это,

public interface Taxrate
{
    string Name { get; }
    decimal Rate { get; }
}

public class NormalTaxRate : Taxrate
{
    public string Name
    { get { return "Regelsteuersatz"; } }

    public decimal Rate
    { get { return 20m; } }
}

Но тогда мне пришлось бы создать какой-то список, содержащий два экземпляра этих двух объектов. Выполнение статики может сработать, но мне все равно придется вести какой-то список. Также мне нужно найти способ сопоставить мой объект домена POCO с этим, потому что я сомневаюсь, что NHibernate может создать экземпляр нужного объекта в зависимости от значения в поле.

Это не совсем правильно, и я думаю, что мне здесь чего-то не хватает. Надеюсь, у кого-то есть лучшее решение, я не могу придумать одно.

привет, Даниил

Ps: также, пожалуйста, пометьте этот вопрос, если вы найдете что-то подходящее, я не могу думать о более значимых тегах прямо сейчас.

Ответы [ 5 ]

6 голосов
/ 28 ноября 2008

РЕДАКТИРОВАТЬ: обратите внимание, что код здесь может быть сокращен, если частный конструктор берет налоговую ставку и имя. Я предполагаю, что в реальной жизни могут существовать реальные поведенческие различия между налоговыми ставками.

Звучит так, как будто вы хотите что-то вроде перечислений Java.

C # делает это довольно сложно, но вы можете сделать это до некоторой степени, используя частные конструкторы и вложенные классы:

 public abstract class TaxRate
 {
     public static readonly TaxRate Normal = new NormalTaxRate();
     public static readonly TaxRate Whatever = new OtherTaxRate();

     // Only allow nested classes to derive from this - and we trust those!
     private TaxRate() {}

     public abstract string Name { get; }
     public abstract decimal Rate { get; }

     private class NormalTaxRate : TaxRate
     {
         public override string Name { get { return "Regelsteuersatz"; } }
         public override decimal Rate { get { return 20m; } }
     }

     private class OtherTaxRate : TaxRate
     {
         public override string Name { get { return "Something else"; } }
         public override decimal Rate { get { return 120m; } }
     }
 }

Возможно, вы захотите, чтобы какой-то статический метод в TaxRate возвращал правильный экземпляр на основе имени или чего-либо еще.

Я не знаю, насколько легко это сочетается с NHibernate, но, надеюсь, это поможет в некоторой степени ...

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

// TaxRate.cs
public partial abstract class TaxRate
{
    // All the stuff apart from the nested classes
}

// TaxRate.Normal.cs
public partial abstract class TaxRate
{
    private class NormalTaxRate : TaxRate
    {
        public override string Name { get { return "Regelsteuersatz"; } }
        public override decimal Rate { get { return 20m; } }
    }
}

// TaxRate.Other.cs
public partial abstract class TaxRate
{
    private class OtherTaxRate : TaxRate
    {
        public override string Name { get { return "Something else"; } }
        public override decimal Rate { get { return 120m; } }
    }
}

Затем вы можете изменить файл проекта, чтобы показать вложенные классы как дочерние классы внешнего класса, как показано в этом вопросе SO .

3 голосов
/ 28 ноября 2008

Я бы сделал это так:

public class TaxRate
{
    public readonly string Name;
    public readonly decimal Rate;

    private TaxRate(string name, decimal rate)
    {
        this.Name = name;
        this.Rate = rate;
    }


    public static readonly TaxRate NormalRate = new TaxRate("Normal rate", 20);
    public static readonly TaxRate HighRate = new TaxRate("High rate", 80);
}

Таким образом, его будет легко использовать - просто получите доступ к TaxRate статическим элементам, таким как значения enum. Чтобы использовать его с NHibernate, вам нужно будет создать собственный класс типов NHibernate (см. Документацию), но это не так сложно. Я уже сделал это однажды.

1 голос
/ 28 ноября 2008

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

Хотя на данный момент это может показаться логичным решением избежать сохранения НДС и налоговых ставок в базе данных, время покажет, что вы ошибаетесь. Во-первых, вы всегда должны иметь возможность извлекать данные, как это было в определенный момент времени, и для этого вам нужно управлять версиями ставок.

Как мы знаем, единственная константа - это изменение. Скажите, что цены изменяются (они будут). Если вы потеряли доступ к источнику, вы не сможете обеспечить надлежащее обслуживание. Если бы ставки были разделены с фиксированного НДС на разные ставки, обновление системы было бы еще сложнее.

Эта проблема не решена. Великобритания снизила НДС с 17,5% до 15% с 1 декабря. Многие люди застряли со старым программным обеспечением без возможности обновления ставок. Пожалуйста, избегайте этой ошибки (и разделение ставок на базу данных также даст много других улучшений).

1 голос
/ 28 ноября 2008

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

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

Таким образом, у вас будет класс TaxRate с Id / Description / Rate (*). Вы можете загрузить словарь со всеми возможными значениями для быстрого поиска по курсу / описанию по идентификатору.

(*) в многоязычном приложении вам необходимо найти локализованное описание для каждой пары Culture / Id - либо из второй таблицы в базе данных, либо из ресурсов и т. Д.

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

1 голос
/ 28 ноября 2008

Почему бы не сохранить налоговые ставки в конфигурации приложения, например, в файле web.config или app.config? Это простые XML-файлы, в которых есть раздел, в котором можно указать пользовательские параметры с ключом и значением. Например:

<appSettings>
    <add key="BaseTaxRate" value=20"/>
    <add key="HigherTaxRate" value=40"/>
</appSettings>

Затем вы можете получить их в своем приложении просто:

string baseTaxRate = ConfigurationSettings.AppSettings["BaseTaxRate"];

Таким образом, они легко изменяются и не требуют повторной компиляции и повторного развертывания вашего приложения.

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

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