通过属性列表作为参数

时间:2018-07-23 11:26:48

标签: c#

希望通过一个类的属性列表,然后读取针对通过以下每个属性持有的自定义属性:

class Foo 
{
    [FooBar(Name="Prop1")]
    public string Prop1 { get; set; }

    [FooBar(Name="Prop2")]
    public int Prop2 { get; set; }

    [FooBar(Name="Prop3")]
    public bool Prop3 { get; set; }
}

// unsure of the props parameter type here
public List<string> GetAttr(Expression<List<Func<Foo, object>>> props)
{
    foreach(var prop in props)
    {
        // get FooBar attributes name value of the properties passed in
    }
}

然后按以下方式引用:

GetAttr(bar => { bar.Prop1, bar.Prop2 });

将返回:

"Prop1", "Prop2"

我已经通过将参数定义为params Expression >>使其工作,但这最终变得非常冗长,因为每次都需要指定条形参考:

GetAttr(bar => bar.Prop1, bar => bar.Prop2);

虽然可行,但比我要替换的系统更冗长。

目的是能够指定列表中返回的属性

编辑: 在另一个属性中添加了示例代码。

1 个答案:

答案 0 :(得分:1)

您可以尝试使用此代码吗?

我的想法是创建Type的扩展名以获取每个属性的属性值。该方法会收到一个包含您要获取其值的所有属性的表达式。

 public static TValue[] GetAttributeValue<TClass, TAttribute, TValue>(
        this Type type,
        Func<TAttribute, TValue> valueSelector,
        Expression<Func<TClass, object>> properties)
        where TAttribute : Attribute
    {
        var rs = new List<TValue>();
        PropertyInfo[] props = type.GetProperties();

        //find the name of properties in the expression
        MemberExpression body = properties.Body as MemberExpression;
        var fields = new List<string>();
        if (body == null)
        {
            NewExpression ubody = properties.Body as NewExpression;
            if (ubody != null)
                foreach (var arg in ubody.Arguments)
                {
                    fields.Add((arg as MemberExpression).Member.Name);
                }
        }

        //get attributes of the properties allowed
        foreach (PropertyInfo prop in props)
        {
            if (!fields.Contains(prop.Name))
                continue;

            var att = prop.GetCustomAttributes(
           typeof(TAttribute), true).FirstOrDefault() as TAttribute;
            if (att != null)
            {
                rs.Add(valueSelector(att));
            }                
        }           
        return rs.ToArray();
    }

并像这样使用:

 var rs = typeof(Foo).GetAttributeValue((FooBar fb) => fb.Name, (Foo p) => new { p.Prop1, p.Prop2 });