views:

40

answers:

1

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?

+1  A: 

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
 }
}
consultutah