MinValue&属性的MaxValue属性

时间:2013-11-16 13:41:28

标签: c# attributes

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

示例:

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

所以这就像MinValue(1)

5 个答案:

答案 0 :(得分:4)

尽管可以创建自定义属性,但属性只是他们注释的成员的元数据,并且无法更改其行为。

因此,您不会使用普通属性获得所需的行为。您需要处理属性才能实现所需的行为。

查看TypeConverters的可能性。

答案 1 :(得分:4)

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

答案 2 :(得分:3)

是的,有可能。在MSDN了解自定义属性。

顺便说一下,你已经有了一个可以使用的解决方案。它是RangeAttribute,允许您为数据字段的值指定数值范围约束。请在MSDN上了解详情。

答案 3 :(得分:1)

是的,可以使用(已经指出)CustomAttributes,但请注意,您将失去自动属性的舒适度 - 因为您需要应用resp。在某处检查属性限制,在这种情况下,适当的位置将是属性的getter,因此问题的有趣部分是属性的应用。您可以阅读如何访问自定义属性in this MSDN article

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条件将小于而不是大于

答案 4 :(得分: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); } }