создание пользовательского атрибута для управления поведением округления - PullRequest
0 голосов
/ 02 декабря 2009

У меня есть класс с большим количеством десятичных свойств, которые используются для финансовых расчетов. Существуют правила, которые определяют количество десятичных знаков, используемых при округлении каждого числа. Глобального правила не существует - некоторые представляют собой два десятичных знака, некоторые 0, некоторые 8 и т. Д.

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

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

Возможно ли это? Если да, то каков хороший пример того, как подойти к этому?

Если нет, есть ли другие методы, которые я должен рассмотреть, кроме пользовательского сеттера?

1 Ответ

2 голосов
/ 02 декабря 2009

Вы можете сделать это с помощью PostSharp или какой-либо другой платформы AOP на основе .NET. Вот свойство 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
    }
}
...