创建自定义属性来控制舍入行为

发布于 2024-08-13 07:24:35 字数 336 浏览 5 评论 0原文

我有一个包含许多用于财务计算的 Decimal 属性的类。有一些规则指定在对每个数字进行四舍五入时要使用多少位小数。没有全局规则 - 有些是两位小数,有些是 0,有些是 8 等。

我试图找出解决这个问题的最简单方法。我想避免舍入逻辑遍布代码中的各处。我知道我可以为每个属性编写一个自定义设置器,在分配它时对值进行四舍五入。

这似乎是我可以使用自定义属性完成的事情。然而,我以前没有编写过自定义属性,而且我找不到一个很好的例子来完成与我想要的类似的事情,所以我可能找错了树。

这可能吗?如果是这样,有什么很好的例子来说明如何解决这个问题?

如果没有,除了自定义设置器之外,我还应该考虑其他方法吗?

I have a class with a lot of Decimal properties that are used for financial calculations. There are rules that specify how many decimal places to use when rounding each number. There is no global rule - some are two decimal places, some 0, some 8, etc.

I'm trying to figure out the easiest way to approach this. I want to avoid having rounding logic spread all over the place in my code. I know I can write a custom setter for each property that rounds the value when I assign it.

This seems like something I could do with a custom attribute. However, I haven't written a custom attribute before, and I can't find a good example that does something similar to what I want, so I might be barking up the wrong tree.

Is this possible? If so, what's a good example of how to approach this?

If not, are there any other methods I should consider other than the custom setter?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酒绊 2024-08-20 07:24:35

您可以使用 PostSharp 或其他一些基于 .NET 的 AOP 框架来完成此操作。这是 MethodExecutionEventArgs.ReturnValue 属性 表示它可用于“修改返回值...”

这将做到这一点:

[Serializable]
public class RoundingAttribute : OnMethodBoundaryAspect
{
    public override void OnExit(MethodExecutionEventArgs eventArgs)
    {
        base.OnExit(eventArgs);
        eventArgs.ReturnValue = Math.Round((double)eventArgs.ReturnValue, 2);
    }
}

class MyClass
{
    public double NotRounded { get; set; }

    public double Rounded { [Rounding] get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var c = new MyClass
                {
                    Rounded = 1.99999, 
                    NotRounded = 1.99999
                };

        Console.WriteLine("Rounded = {0}", c.Rounded); // Writes 2
        Console.WriteLine("Not Rounded = {0}", c.NotRounded);  // Writes 1.99999
    }
}

You could do this with PostSharp or some other .NET-based AOP framework. Here is the MethodExecutionEventArgs.ReturnValue property that says it can be used to "modify the return value..."

This will do it:

[Serializable]
public class RoundingAttribute : OnMethodBoundaryAspect
{
    public override void OnExit(MethodExecutionEventArgs eventArgs)
    {
        base.OnExit(eventArgs);
        eventArgs.ReturnValue = Math.Round((double)eventArgs.ReturnValue, 2);
    }
}

class MyClass
{
    public double NotRounded { get; set; }

    public double Rounded { [Rounding] get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var c = new MyClass
                {
                    Rounded = 1.99999, 
                    NotRounded = 1.99999
                };

        Console.WriteLine("Rounded = {0}", c.Rounded); // Writes 2
        Console.WriteLine("Not Rounded = {0}", c.NotRounded);  // Writes 1.99999
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文