2008-11-28 4 views
4

Мне интересно, как вы подходите к этой проблемеEnum struct? A Объект Value, который ведет себя как Enum

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

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

Я мог бы пойти с Enum, который отображает значение. Но тогда мне придется создать какой-то метод, который извлекает имя этого налога для английского значения 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 может создать экземпляр нужного объекта в зависимости от значения в поле.

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

поздравления, Daniel

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

ответ

6

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

Похоже, вы хотите что-то вроде перечислений 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; } } 
    } 
} 

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

+0

Как уродливо, как выглядит, Скитер прав ... это не плохое решение: P Я бы также переопределил процесс преобразования по умолчанию, чтобы вы могли конвертировать из десятичного числа в один из этих экземпляров. – 2008-11-28 11:29:35

+0

BTW: Я только думаю, что это уродливо, потому что оно смешалось вместе. – 2008-11-28 11:30:19

1

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

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

Вы можете получить эти в вашем приложении просто:

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

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

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

2

Я хотел бы сделать это следующим образом:

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 статических элементов, как значения перечислений. Чтобы использовать его в NHibernate, вам нужно будет создать свой собственный класс типа NHibernate (см. Документацию для него), но это не так сложно. Я уже это сделал.

1

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

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

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

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

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

1

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

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

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

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

Смежные вопросы