属性的 MinValue 和 MaxValue 属性



是否可以创建可以限制数字最小值或最大值的属性。

例:

[MinValue(1), MaxValue(50)]
public int Size { get; set; }

当我这样做时Size = -3; Size的值必须是 1。

我在谷歌上搜索了一下,找不到关于这种行为的单一例子,也许是因为不可能制作?

我将在属性网格中使用这些属性,因此进行自动验证会很方便。

目前,我像这样解决问题来限制最小值:

    private int size;
    [DefaultValue(8)]
    public int Size
    {
        get
        {
            return size;
        }
        set
        {
            size = Math.Max(value, 1);
        }
    }

所以这就像最小值(1)

尽管可以创建自定义属性,但属性只是它们批注的成员的元数据,不能更改其行为。

因此,您将不会获得具有纯属性的所需行为。您需要一些东西来处理属性,以便制定所需的行为。

看看类型转换器的可能性。

是的,这是可能的。阅读有关 MSDN 上的自定义属性的信息。

顺便说一下,已经有一个您可以使用的解决方案。它是允许您为数据字段的值指定数值范围约束的RangeAttribute。在 MSDN 上阅读有关它的更多信息。

您可以通过编写简单的方面来优雅地使用 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。

创建扩展

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); } }

是的,使用(已经指向的)CustomAttributes 是可能的,但请注意,您将失去自动属性的舒适性 - 因为您需要在某处应用或检查属性限制,在这种情况下,适当的位置将是属性的获取者,因此问题的有趣部分是属性的应用。您可以在这篇 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

最小值的代码看起来与最大值的代码相同,但 if 条件将小于而不是大于

最新更新