C# 获取属性修饰属性的值
我想在类中进行一些验证,所以我想我可以使用属性。 像这样:C# 获取属性修饰属性的值,c#,validation,maxlength,C#,Validation,Maxlength,我想在类中进行一些验证,所以我想我可以使用属性。 像这样: public class someClass { [Lenght(200)] public string someStr { get; set; } } [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] sealed class Lenght : Attribute { public Lenght(in
public class someClass
{
[Lenght(200)]
public string someStr { get; set; }
}
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
sealed class Lenght : Attribute
{
public Lenght(int Lenght)
{
//some code
}
}
但我知道我做不到,因为这不是属性的工作方式。而且,如果有办法的话,它将使用某种我想要避免的沉重反思和混乱
我想做的验证如下:
public class someClass
{
public string someStr
{
get
{
return _someStr;
}
set
{
if (value.Length > 200)
{
throw new Exception("Max Length is 200!");
}
else _someStr = value;
}
}
private string _someStr { get; set; }
}
但是我想做得更快,没有这些代码。我想要和使用属性一样快
有一种方法可以做到吗?属性的目的是向其他组件、工具、编译器等声明有关程序集、类型、成员、参数等的元数据。当然,您可以按要求执行,但这将涉及到反思自身,这是一个很长的路要走,只是主张的价值,因为你在你的第二个例子
您应该考虑的是一个验证框架,它为您构建了所有这些东西,并允许您分别和外部验证。 有许多验证框架可供选择。我脑海中最流行的两个是和企业图书馆的
另一方面,也许你只是在寻找一个好的班级或学校。它们的用途与验证不同(参见)。您可以将属性(我建议重用)与一些面向方面的编程结合起来,以声明的方式为您完成保护工作(请参阅)。但是,这可能只是在炫耀:)。您可以创建一个将字段作为
ref
参数的方法:
public static void SetWithMaxLength(ref string field, string value, int maxLength)
{
if(value.Length > maxLength) throw new Exception("Max length is " + maxLength);
field = value;
}
然后您可以将setter编写为:
set
{
SetWithMaxLength(ref this._someStr, value, 200);
}
通常情况下,您不会使用属性执行类似的操作,但这是可能的,尽管不推荐。使用时自担风险:)(如果该酒店没有使用
长度属性装饰,您会大发雷霆。
:)
public接口AttributeValidator
{
void CheckOk(对象值);
}
公共类LenghtAttribute:属性,AttributeValidator
{
public int MaxLength{get;private set;}
公共长度属性(整数长度)
{
this.MaxLength=长度;
}
公共无效检查确定(对象值)
{
var str=字符串形式的值;
如果(str!=值)
抛出新异常(“不是字符串!”);
如果(str!=null&&str.Length>MaxLength)
抛出新异常(“到long!”);
}
}
公共类不包含:属性,AttributeValidator
{
公共字符串字符{get;private set;}
公共不包含(字符串字符)
{
this.Chars=Chars;
}
公共无效检查确定(对象值)
{
var str=字符串形式的值;
如果(str!=值)
抛出新异常(“不是字符串!”);
if(str!=null&&Chars.Any(c=>str.Contains(c)))
抛出新异常(“包含禁止字符!”);
}
}
公共类
{
私有字符串_someString;
[长度(200)]
[不包含($#2”)]
公共字符串SomeString
{
获取{return\u someString;}
设置
{
验证(“SomeString”,this,value);
_someString=值;
}
}
}
公共静态类Utils
{
公共静态void验证(字符串属性、对象实例、字符串值)
{
var validators=instance.GetType().GetProperty(属性)
.GetCustomAttributes(false).OfType();
foreach(验证器中的var验证器)
验证器.CheckOk(值);
}
}
编辑我扩展了示例。这仍然是一个糟糕的解决方案,但它很有效。是的,我可以研究更多关于ref和out参数的信息。。。谢谢这个FluentValidation框架似乎很有趣,但我不喜欢使用框架进行基本验证的想法……但它似乎很有趣……我发布这个问题已经两年了,今天我在这里回顾了我的问题。从那时起,我学到了一些C#,现在我不会问这个问题,也不会使用属性来验证它。我接受了你的答案,因为你付出了一些努力,我只想指出,你在SomeClass中的代码所做的事情与我在问题中发布的几乎相同,但不管怎样。另外,在拥有了一些属性内验证的经验之后,我再也不想这样做了,我也不希望在属性内抛出异常。从那以后我完全改变了主意。
public interface AttributeValidator
{
void CheckOk(object value);
}
public class LenghtAttribute : Attribute, AttributeValidator
{
public int MaxLength { get; private set; }
public LenghtAttribute(int lenght)
{
this.MaxLength = lenght;
}
public void CheckOk(object value)
{
var str = value as string;
if (str != value)
throw new Exception("Not a string!");
if (str != null && str.Length > MaxLength)
throw new Exception("To long!");
}
}
public class DoesNotContain : Attribute, AttributeValidator
{
public string Chars { get; private set; }
public DoesNotContain(string chars)
{
this.Chars = chars;
}
public void CheckOk(object value)
{
var str = value as string;
if (str != value)
throw new Exception("Not a string!");
if (str != null && Chars.Any(c => str.Contains(c)))
throw new Exception("Contains forbidden character!");
}
}
public class SomeClass
{
private string _someString;
[Lenght(200)]
[DoesNotContain("$#2")]
public string SomeString
{
get { return _someString; }
set
{
Utils.Validate("SomeString", this, value);
_someString = value;
}
}
}
public static class Utils
{
public static void Validate(string property, object instance, string value)
{
var validators = instance.GetType().GetProperty(property)
.GetCustomAttributes(false).OfType<AttributeValidator>();
foreach (var validator in validators)
validator.CheckOk(value);
}
}