假设您有一个具有300个属性而没有支持变量的类,每个属性都返回一个十进制/双精度。
示例:
public decimal MathValue { get; set; }
现在你决定将每个值都舍入。
我正在寻找最简单的重构方法,而不必重写所有这些属性。
实际上有效的东西:D:
public decimal MathValue { get {return Math.Round(MathValue);} set; }
答案 0 :(得分:6)
没有。如果在getter或setter中需要任何自定义逻辑,则不能使用自动属性。
答案 1 :(得分:5)
您可以创建一个假装为小数的新值类型,但返回舍入值。像这样:
struct RoundedDecimal
{
public decimal Value { get; private set; }
public RoundedDecimal(decimal value) : this()
{
this.Value = value;
}
public static implicit operator decimal(RoundedDecimal d)
{
return Math.Round(d.Value);
}
}
您班级中的每个媒体资源都应为RoundedDecimal
,而不是decimal
。
答案 2 :(得分:4)
重构代码的最简单方法?这就是我要做的事情:
现在,您需要定义一组对应的私有变量,这些变量以下划线开头,但与属性具有相同的名称。从您班级的新属性副本开始,然后按照上述步骤执行类似的步骤。
我的假设是每行以2个制表符开头,属性之间没有空行。
您可能需要考虑定义自己调用的自己的实用程序函数,而不是让每个属性调用Math.Round,这样如果您需要再次更改它,您可以在一个地方更改它。
答案 3 :(得分:1)
您可以创建此类的派生,以覆盖gets并返回舍入值。然后,您需要将基本属性修改为虚拟。但这样就可以在不定义集合和使用自动属性的情况下定义get。
public class Base
{
public virtual decimal MathValue { get; set; }
}
public class Derived : Base
{
public override decimal MathValue
{
get { return Math.Round(base.MathValue); }
}
}
答案 4 :(得分:0)
但是如果客户端不想要舍入值会发生什么?即,一些新的客户端代码设置一个小数,并期望“准确”值回来?
如果某些客户端确实需要对属性调用的输出进行舍入,那么客户端应该处理此问题并让您的课程独自完成。
答案 5 :(得分:0)
Visual Studio曾经有一个内置的“prop”代码片段,可以生成如下代码:
private decimal _MathValue;
public decimal MathValue
{
get { return _MathValue; }
set { _MathValue = value; }
}
这将使您获得完整解决方案的大部分,但自VS 2008以来它现在生成自动属性版本:
public decimal MathValue { get; set; }
答案 6 :(得分:0)
一种选择是使用面向方面的编程在返回时拦截属性调用,并在将控制权传递给调用者之前舍入返回值。
答案 7 :(得分:0)
您可以使用PostSharp或其他一些基于.NET的AOP框架执行此操作。这是MethodExecutionEventArgs.ReturnValue property,表示它可以用来“修改返回值...”
这样做:
[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
}
}