属性的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); } }