属性的MinValue和MaxValue属性
是否可以创建可以限制数字的最小值或最大值的属性。
例:
[MinValue(1), MaxValue(50)] public int Size { get; set; }
当我做Size = -3;
Size
值必须为1。
我在谷歌搜索过,找不到关于这种行为的单一例子,也许是因为它无法制作?
我将在属性网格中使用这些属性,因此具有自动validation可以很方便。
目前我像这样解决方法来限制最小值:
private int size; [DefaultValue(8)] public int Size { get { return size; } set { size = Math.Max(value, 1); } }
所以这就像MinValue(1)
虽然可以创建自定义属性,但属性只是它们注释的成员的元数据,并且不能更改其行为。
因此,您不会使用普通属性获得所需的行为。 您需要一些东西来处理属性才能实现所需的行为。
看一下TypeConverters的可能性。
你可以通过编写简单的方面使用PostSharp来优雅地解决这个问题,免费版本就足够了:
[Serializable] class RangeAttribute : LocationInterceptionAspect { private int min; private int max; public RangeAttribute(int min, int max) { this.min = min; this.max = max; } public override void OnSetValue(LocationInterceptionArgs args) { int value = (int)args.Value; if (value < min) value = min; if (value > max) value = max; args.SetNewValue(value); } }
然后随心所欲:
class SomeClass { [Range(1, 50)] public int Size { get; set; } }
正常使用:
var c = new SomeClass(); c.Size = -3; Console.Output(c.Size);
将输出1。
对的,这是可能的。 阅读MSDN上的自定义属性。
顺便说一下,你已经有了一个可以使用的解决方案。 RangeAttribute
允许您为数据字段的值指定数值范围约束。 在MSDN上阅读更多相关信息。
是的,可以使用(已经指出)CustomAttributes,但请注意,您将失去自动属性的舒适度 – 因为您需要应用resp。 在某处检查属性限制,在这种情况下,适当的位置将是属性的getter,因此问题的有趣部分是属性的应用。 您可以在此MSDN文章中了解如何访问自定义属性。
MaxValue自定义属性的可能解决方案如下所示:
// simple class for the example public class DataHolder { private int a; [MaxValue(10)] public int A { get { var memberInfo = this.GetType().GetMember("A"); if (memberInfo.Length > 0) { // name of property could be retrieved via reflection var mia = this.GetType().GetMember("A")[0]; var attributes = System.Attribute.GetCustomAttributes(mia); if (attributes.Length > 0) { // TODO: iterate over all attributes and check attribute name var maxValueAttribute = (MaxValue)attributes[0]; if (a > maxValueAttribute.Max) { a = maxValueAttribute.Max; } } } return a; } set { a = value; } } } // max attribute public class MaxValue : Attribute { public int Max; public MaxValue(int max) { Max = max; } }
样本用法:
var data = new DataHolder(); data.A = 12; Console.WriteLine(data.A);
创建输出:
10
MinValue的代码与MaxValue的代码相同,但if条件将小于而不是大于 。
创建一个扩展
public static class Extensions { public static int FixedValue(this int value, int min, int max) { if (value >= min && value <= max) return value; else if (value > max) return max; else if (value < min) return min; else return 1; } }
然后:
private int size; public int Size { get { return size.FixedValue(1, 50); } set { size = value.FixedValue(1, 50); } }