Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取属性修饰属性的值_C#_Validation_Maxlength - Fatal编程技术网

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