【问题标题】:Dynamically get class attribute value from type从类型中动态获取类属性值
【发布时间】:2013-01-04 19:15:36
【问题描述】:

我正在尝试编写一种方法来查找程序集中具有特定自定义属性的所有类型。我还需要能够提供一个字符串值来匹配。需要注意的是,我希望能够在任何类上运行它并返回任何值。

例如: 我想执行这样的调用

Type tTest = TypeFinder.GetTypesWithAttributeValue(Assembly.Load("MyAssembly"), typeof(DiagnosticTestAttribute), "TestName", "EmailTest");

到目前为止,我的方法如下所示:

public static Type GetTypesWithAttributeValue(Assembly aAssembly, Type tAttribute, string sPropertyName, object oValue)
{
    object oReturn = null;
    foreach (Type type in aAssembly.GetTypes())
    {
        foreach (object oTemp in type.GetCustomAttributes(tAttribute, true))
        {
            //if the attribute we are looking for matches
            //the value we are looking for, return the current type.
        }
    }
    return typeof(string); //otherwise return a string type
}

我的属性如下所示:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class DiagnosticTestAttribute : Attribute
{
    private string _sTestName = string.Empty;

    public string TestName
    {
        get { return _sTestName; }
    }
    public DiagnosticTest(string sTestName)
    {
        _sTestName = sTestName;
    }
}

对于那些熟悉表达的人,我真的很想能够拨打这样的电话:

TypeFinder.GetTypesWithAttributeValue<DiagnosticTestAttribute>(Assembly.Load("MyAssembly"), x=> x.TestName, "EmailTest");

表达式使用我的泛型类型来选择我正在寻找的属性。

【问题讨论】:

    标签: c# reflection custom-attributes linq-expressions


    【解决方案1】:

    这应该可行:

    public static Type GetTypeWithAttributeValue<TAttribute>(Assembly aAssembly, Func<TAttribute, object> pred, object oValue) {
      foreach (Type type in aAssembly.GetTypes()) {
        foreach (TAttribute oTemp in type.GetCustomAttributes(typeof(TAttribute), true)) {
          if (Equals(pred(oTemp), oValue)) {
            return type;
          }
        }
      }
      return typeof(string); //otherwise return a string type
    }
    

    甚至更好:

    public static Type GetTypeWithAttributeValue<TAttribute>(Assembly aAssembly, Predicate<TAttribute> pred) {
      foreach (Type type in aAssembly.GetTypes()) {
        foreach (TAttribute oTemp in type.GetCustomAttributes(typeof(TAttribute), true)) {
          if (pred(oTemp)) {
            return type;
          }
        }
      }
      return typeof(string); //otherwise return a string type
    }
    

    这是调用的样子:

      GetTypeWithAttributeValue<DefaultValueAttribute>(Assembly.GetCallingAssembly(), attribute => attribute.Value,
                                                        "string");
    

    和这个分别:

      GetTypeWithAttributeValue<DefaultValueAttribute>(Assembly.GetCallingAssembly(),
                                                        attribute => attribute.Value == "string");
    

    【讨论】:

    • 这工作完美无缺。我不得不更改程序集,因为我从另一个程序集调用它,但它工作得很好。非常感谢。
    • 如果我能给你更多的信任我会;-)
    【解决方案2】:

    很久以前我开发了一些辅助方法来从表达式中提取属性名称,

    我认为这对你有用。

    public static string Item<TItem, TMember>(this TItem obj, Expression<Func<TItem, TMember>> expression)
    {
        if (expression.Body is MemberExpression)
        {
            return ((MemberExpression)(expression.Body)).Member.Name;
        }
        if (expression.Body is UnaryExpression)
        {
            return ((MemberExpression)((UnaryExpression)(expression.Body)).Operand).Member.Name;
        }
        if (expression.Body is ParameterExpression)
        {
            return expression.Body.Type.Name;
        }
        throw new InvalidOperationException();
    }
    

    查看this file 了解更多信息。

    【讨论】:

    • 这很有帮助。一旦我能弄清楚如何从实例类的属性中提取值,这应该可以帮助我为我的方法创建一个很好的接口。谢谢!
    猜你喜欢
    • 2011-09-01
    • 2017-05-27
    • 2017-01-15
    • 1970-01-01
    • 2020-01-29
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    相关资源
    最近更新 更多