为类属性创建自定义属性

时间:2016-06-29 14:38:12

标签: c# attributes

我正在研究控制台应用程序。我想确保当分配给我的类属性的值时,它应该进行基本验证。我读到了“创建自定义属性”但无法理解如何在我的情况下实现。例如

public class MyClass
{
    [Required]
    public string id;

    [ContainsNumeric]
    public int cost;

    [ContainsChar]
     ...

    [ContainsDate]
    ....
} 

我创建了Required属性和ContainsNumeric only类,但不知道如何访问这些类中的实际类属性。

class ContainsNumericAttribute : Attribute
    {
        public ContainsNumericAttribute() : base()
        {
                   ?????
        }
    }
class RequiredAttribute : Attribute
    {
        public RequiredAttribute() : base()
        {
                ???
        }
    }

请帮我举例。

3 个答案:

答案 0 :(得分:0)

我认为您错误地了解属性是什么以及它们如何工作。他们不会在这里添加任何验证,除非你自己的代码检查它们的存在,并调用代码做那个(或者除非你使用IL-rewriter做同样的事情,比如后尖锐)。

基本上:这不会做你想做的事。

答案 1 :(得分:0)

这是如何使用Reflection访问属性:

(当然你需要将它移到某个帮助类或其他东西)。

static bool Validate<T>(T obj)
{
    var properties = obj.GetType().GetProperties().ToList();

    foreach(var prop in properties)
    {
        if(prop.IsDefined(typeof(RequiredAttribute)))
        {
            object value = prop.GetValue(obj);

            if(value == null)
            {
                // do something
            }
        }

        if(prop.IsDefined(typeof(ContainsNumericAttribute)))
        {

        }
    }

    return false; // dummy value now
}

用法:

MyClass cc = new MyClass()
{
    cost = 5
};

Validate(cc); // false, id required

如果需要,可以创建验证结果对象并从Validate方法返回,将所有未通过的验证添加到该对象。

答案 2 :(得分:0)

属性不应该像那样使用。如果你真的想要,你必须做一些非常复杂的反思,在运行时获取这些属性,并检查它们的值......这真是一团糟!

我建议你创建一个PropertyValidatorClass

public static class PropertyValidator {
    public static bool Required<T>(T property) where T: class {
        // I think you want to check this?
        return property != nil;
    }

    public static bool ContainsNumeric(string property) {
        return ...
    }

    public static bool ContainsDate(string property) {
        return ...
    }

    public static bool ContainsChar(string property) {
        return ...
    }

    ...
}

在每个房产的制定者中

set {
    if (PropertyValidator.Required(value)) {
        Id = value;
    } else {
        // I dunno, throw an exception or something
    }
}

你也可以修改这个类,以便你有一个流畅的界面:

using static SomeNamespace.PropertyValidator;
...
if (Check(value, withRule: Rules.Required))

Rules显然是枚举,Check是来自PropertyValidator的方法。

这只是我的一些想法。