是否可以创建可以限制数字最小值或最大值的属性。
例:
[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 条件将小于而不是大于。