繁体   English   中英

如何判断一个属性是否需要?

[英]How to determine if a property is required?

给定一个 class 这样的东西:

public class MyClass : ValidationValues
{
    public string Foo { get; set; }

    [Required(ErrorMessage = "Bar is required.")]
    public string Bar { get; set; }
    
    // and many more
}

public class ValidationValues
{
    public bool IsValid { get; set; } = true;
    public string InvalidReason { get; set; }
}

我需要确定是否需要属性,同时将其作为通用列表循环。 通过查看 Watch,我找到了一种方法,但感觉很笨拙,我认为它应该更简单。

对于某些上下文,此逻辑在 Azure Function 内部。因此没有视图,没有 MVC 等。function 是一个 Blob 存储触发器,它使用 | 拾取 a.CSV 文件。 被反序列化为List<MyClass>的定界列表。 我们不想在反序列化时强制执行Required属性,因为我们想要更精细的控制。

所以给出这样的文件:

value1 | |
value2 | something

最终返回给用户的是这样的:

[
    {
        "foo": "value1",
        "bar": "",
        "isValid": false,
        "InvalidReason" : "Bar is required"
    },
    {
        "foo": "value2",
        "bar": "something",
        "isValid": true,
        "InvalidReason" : ""
    }
]

这是我现在拥有的:

foreach (T item in itemList) // where 'itemList' is a List<T> and in this case T is MyClass
{
    foreach (PropertyInfo property in item.GetType().GetProperties())
    {
        if (property.CustomAttributes.ToList()[0].AttributeType.Name == "RequiredAttribute")
        {
             // validate, log, populate ValidationValues
        }
    }
}

这是我不喜欢的部分:

property.CustomAttributes.ToList()[0].AttributeType.Name == "RequiredAttribute"

有时当我想出一个编码挑战时,我告诉自己,“就是这样”。 但在这种情况下,我很确定这不是方法。

反射很慢——或者至少,相对较慢。 所以; 这里最重要的是:不要对每个实例都这样做; 您可以按Type缓存它(来自GetType() ,或者您可以只使用T而从不检查每个实例的.GetType() ,具体取决于您的意图。这包括缓存给定类型存在的属性,以及哪些是required. 然而,真正的奖励点是使用元编程来发出 - 无论是在运行时,还是在构建时通过“生成器” - 一种完全按照你想要的方式执行的方法,没有任何循环,测试等;即在这种情况下,它可能会发出一个方法,它相当于

void ValidateMyClass(MyClass obj)
{
    if (string.IsNullOrWhitespace(obj.Bar))
    {
        DoSomething("Bar is required.");
    }
}

这可以通过多种方式完成,包括Expression API、发出 API ( ILGenerator )、发出 C# 并使用CSharpCodeProvider或“生成器”API。

您可以使用GetCustomAttibute重写该行:

using System.Reflection;
foreach (T item in itemList) // where 'itemList' is a List<T> and in this case T is MyClass
{
    foreach (PropertyInfo property in item.GetType().GetProperties())
    {
        var attribute = property.GetCustomAttibute<RequiredAttribute>();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM