C# 属性,是否可以绕过定义get而不定义set(无支持变量)?
假设您有一个具有300个属性且没有支持变量的类,每个属性都返回一个十进制/双精度 例如:C# 属性,是否可以绕过定义get而不定义set(无支持变量)?,c#,properties,C#,Properties,假设您有一个具有300个属性且没有支持变量的类,每个属性都返回一个十进制/双精度 例如: public decimal MathValue { get; set; } 现在您决定这些值中的每一个都应该四舍五入 我正在寻找最简单的方法来重构它,而不必重写所有这些属性 public class Base { public virtual decimal MathValue { get; set; } } public class Derived : Base { public o
public decimal MathValue { get; set; }
现在您决定这些值中的每一个都应该四舍五入
我正在寻找最简单的方法来重构它,而不必重写所有这些属性
public class Base
{
public virtual decimal MathValue { get; set; }
}
public class Derived : Base
{
public override decimal MathValue
{
get { return Math.Round(base.MathValue); }
}
}
这个等价物中实际起作用的东西:D:
public decimal MathValue { get {return Math.Round(MathValue);} set; }
否。如果在getter或setter中需要任何自定义逻辑,则不能使用自动属性。您可以创建一个新的值类型,该类型假装为十进制,但返回舍入值。大概是这样的:
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);
}
}
public class Base
{
public virtual decimal MathValue { get; set; }
}
public class Derived : Base
{
public override decimal MathValue
{
get { return Math.Round(base.MathValue); }
}
}
类中的每个属性都应该是
RoundedDecimal
类型,而不是decimal
,但是如果客户端不需要舍入值,会发生什么呢?也就是说,一些新的客户端代码设置了一个十进制数,并期望返回“精确”值
如果一些客户机确实需要对属性调用的输出进行取整,那么客户机应该处理这个问题,让您的类自己处理 您可以创建此类的派生,该派生重写get并返回舍入值。然后需要将基本属性修改为虚拟属性。但这将允许您在不定义集合和使用自动属性的情况下定义get
public class Base
{
public virtual decimal MathValue { get; set; }
}
public class Derived : Base
{
public override decimal MathValue
{
get { return Math.Round(base.MathValue); }
}
}
Visual Studio以前有一个内置的“prop”代码段,它将生成类似以下代码的内容:
private decimal _MathValue;
public decimal MathValue
{
get { return _MathValue; }
set { _MathValue = value; }
}
这将为您提供最完整的解决方案,但自VS 2008以来,它现在会生成自动属性版本:
public decimal MathValue { get; set; }
我还没有尝试过,但是:一个选项是使用面向方面的编程在返回时拦截属性调用,并在将控制权传递回调用方之前对返回值进行取整。重构代码的最简单方法是什么?下面是我要做的:
public class Base
{
public virtual decimal MathValue { get; set; }
}
public class Derived : Base
{
public override decimal MathValue
{
get { return Math.Round(base.MathValue); }
}
}
而不是让每个属性调用Mault.St圆,您可能需要考虑定义自己的实用函数,它们都调用,这样,如果您需要再次更改它,就可以在一个地方更改它。
< P>您可以使用其他基于.NET的AOP框架来实现这一点。" 这可以做到:[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
}
}
如果不为每个变量声明一个变量,绝对没有办法覆盖这个逻辑或解决方案?另一种方法是编写一个命令行util(或者最好使用T4)从其他文件/数据为您生成300个属性。您可以使用类似PostSharp的方法在编译后重写属性。然而,对于这样琐碎的事情,可能不值得这么做。我认为这更多的是一个理论问题,而不是一个暴力问题。。。我愿意接受任何能帮助我用最少代码解决问题的想法。我不知道这是如何回答他的问题的。我称之为
Int96
,因为它实际上就是这样。这是一种在不破坏接口的情况下实现它的好方法。实际上,如果您创建一个名为Value的公共只读字段,并在构造函数中对其进行四舍五入,可能会更好。到目前为止,我最喜欢这个解决方案。:)这也很容易实现。ctrl-h“decimal”“RoundedDecimal”那么在这种情况下,get就可以单独处理:)对于那个特定的属性。。。我唯一想做的就是避免为每个属性声明一个变量。这是如何实现的?如果可能的话,我想覆盖GET本身。你能给我举个例子吗?当然。我还澄清了整个属性需要是虚拟的,而不仅仅是getter。继承在这方面似乎有些过火。对于“是否有可能绕过定义get而不定义set”的问题,我不同意。从更广泛的角度来看,这种方法也为他提供了一个全面和不全面的课程版本。由此产生的类名可以具有更好的语义。然而,我同意,除非他能获得这些特殊的好处,否则这可能是过火了。我更感兴趣的是围绕代码的方式,而不是手动重构类中的所有内容,即使我有一个代码片段可以为我实现。啊,y