C# MinValue&;属性的MaxValue属性
是否可以使属性限制数字的最小值或最大值 例如:C# MinValue&;属性的MaxValue属性,c#,attributes,C#,Attributes,是否可以使属性限制数字的最小值或最大值 例如: [MinValue(1), MaxValue(50)] public int Size { get; set; } 当我做Size=-3大小的值必须为1 我在谷歌上搜索,找不到一个关于这种行为的例子,可能是因为不可能做出这样的决定 我将在属性网格中使用这些属性,因此自动验证非常方便 目前,我的解决办法是限制最小值: private int size; [DefaultValue(8)] public int Size
[MinValue(1), MaxValue(50)]
public int Size { get; set; }
当我做Size=-3代码>大小的值必须为1
我在谷歌上搜索,找不到一个关于这种行为的例子,可能是因为不可能做出这样的决定
我将在属性网格中使用这些属性,因此自动验证非常方便
目前,我的解决办法是限制最小值:
private int size;
[DefaultValue(8)]
public int Size
{
get
{
return size;
}
set
{
size = Math.Max(value, 1);
}
}
这就像MinValue(1)是的,这是可能的。阅读有关自定义属性的信息
顺便说一句,你已经有了一个解决方案。正是RangeAttribute
允许您为数据字段的值指定数值范围约束。请在上阅读更多信息。尽管可以创建自定义属性,但属性只是它们所注释的成员的元数据,不能更改其行为
因此,使用普通属性无法获得所需的行为。为了实现所需的行为,您需要处理属性
看看是否有可能。是的,可以使用(已经指出的)CustomAttributes,但是请记住,您将失去自动属性的舒适性-因为您需要应用resp。在某个地方检查属性限制,在本例中,适当的位置将是属性的getter,因此问题的有趣部分是属性的应用。您可以阅读如何访问自定义属性
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条件将小于而不是大于。您可以通过编写简单方面优雅地解决此问题,免费版本就足够了:
[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);
}
}
正常使用时:
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;
}
}
我已经检查了MSDN,但并没有关于修改属性为attribute的属性集值的内容。我还检查了RangeAttribute,它是用于asp.net数据控件的,当我将它与属性网格一起使用时不会产生任何效果。是的,您似乎不了解属性的用途。乔道在他的回答中解释了这一点。我刚刚就您提出的一个问题发布了一个答案:“是否有可能使属性限制数字的最小值或最大值。”@Jaex您认为它只适用于asp???@OndrejJanacek即使它是“在msdn上阅读”,我还是对我学到的新东西投了赞成票:)Cheers@Noctis在这里:“System.ComponentModel.DataAnnotations命名空间提供用于定义ASP.NET MVC和ASP.NET数据控件元数据的属性类。“PropertyGrid类不会帮助您实现这一点,它对您的自定义属性一无所知。编写自定义类型转换器很痛苦。在属性设置器中强制执行范围是一种简单的方法。感谢您的努力,但不幸的是使用size=Math.Max(value,1)将是一个更优雅的解决方案。这是事实,但这是属性的捕获-在某些点和某些地方需要对属性进行评估和应用,否则如果不使用它们,它们有什么用呢?也许使用propertygrid inherit,在设置值时可以对属性进行评估。但要弄清楚这将是太多的工作,所以我将继续使用Math.Max解决方案。如果不自动更改值,如何通知调用方呢?我可以抛出一个异常吗?
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); } }