4

我想知道你将如何解决这个问题

我有两种适用于我的产品的税率。我特别想避免将税率持久化到数据库中,同时仍然能够在中心位置更改它们(例如税率从 20% 到 19% 等)。

所以我决定将它们编译到我的应用程序中会很棒(它是内部的)。问题是我不仅想知道税率,还想知道税率的名称。

我可以使用映射到该值的枚举。但是我必须创建一些方法来检索英语枚举值的该税率的德语名称(我用英语编写代码,应用程序是德语)。

我想过只使用硬编码的对象来反映这一点,

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:如果你找到合适的东西,也请重新标记这个问题,我现在想不出更有意义的标签。

4

5 回答 5

6

编辑:请注意,这里的代码可以很容易地通过让私有构造函数获取税率和名称来缩写。我假设在现实生活中,税率之间可能存在实际的行为差异。

听起来你想要像 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 question中所示。

于 2008-11-28T11:25:53.240 回答
3

我会这样做:

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 类型类(请参阅它的文档),但这并不难。我已经做过一次了。

于 2008-11-28T12:00:19.040 回答
1

为什么不将税率存储在应用程序配置中,例如在 web.config 或 app.config 文件中?这些是简单的 XML 文件,其中有一个名为的部分,您可以在其中使用键和值指定自定义参数。例如:

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

然后,您可以简单地在应用程序中检索这些:

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

这样,它们很容易更改,并且不需要重新编译和重新部署您的应用程序。

显然,您还可以将税率名称作为额外设置存储在配置文件中。

于 2008-11-28T11:22:33.870 回答
1

我必须说我发现使用嵌套类的想法有点奇怪,因为在我看来这是一种主流要求。

将速率存储在数据库(或其他持久性介质,例如应用程序配置文件)中有什么问题?我原以为您希望每个税率都有一个唯一的 ID,用于产品和税率之间的关系。

因此,您将拥有一个带有 Id/Description/Rate (*) 的 TaxRate 类。您可以加载包含所有可能值的字典,以便按 Id 快速查找速率/描述。

(*) 在多语言应用程序中,您需要查找每对 Culture/Id 的本地化描述 - 从数据库中的第二个表或资源等...

无论如何,硬性税率似乎是错误的——尤其是现在政府正在利用税率来促进经济发展。

于 2008-11-28T14:33:42.553 回答
1

我知道这违背了你问题的主要前提,但我想对这个问题提出一些想法。

虽然目前看来避免在数据库中保留增值税和税率似乎是一个合乎逻辑的决定,但时间会证明你错了。首先,您应该始终能够在给定时间提取数据,为此您需要对速率进行版本控制。

众所周知,唯一不变的就是变化。说利率变化(他们会)。如果您失去了对源的访问权限,则无法进行适当的维护。如果将税率从统一增值税拆分为不同的税率,更新系统将更加困难。

这个问题虽然不是问题。自 12 月 1 日起,英国已将增值税从 17.5% 降至 15%。许多人被旧软件困住而无法更新费率。请避免犯此错误(将费率拆分到数据库中也会带来许多其他改进)。

于 2008-11-28T15:01:47.987 回答