【问题标题】:Access to the value of a Custom Attribute访问自定义属性的值
【发布时间】:2011-06-30 17:00:21
【问题描述】:

我有这个自定义属性:

[AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited = true)]
class MethodTestingAttibute : Attribute
{   
    public string Value{ get; private set; }
    public MethodTestingAttibute (string value)
    {
        this.Value= value;

    }
}

这样使用:

[MethodTestingAttibute("2")]
public int m1() {return 3; }

而我的困难是取MethodTestingAttibute的“2”的值

object result = method.Invoke(obj, new Type[] {}); // here i get the return

现在我想将此结果与MethodTestingAttibute 的值进行比较。我怎样才能做到这一点?我正在尝试走这条路但没有成功:

method.GetCustomAttributes(typeof(MethodTestAttibute), true)[0]...

访问自定义属性字段的正确方法是什么?

【问题讨论】:

标签: c# attributes


【解决方案1】:
var attribute =
   (MethodTestingAttibute)
   typeof (Vehicles)
      .GetMethod("m1")
      .GetCustomAttributes(typeof (MethodTestingAttibute), false).First();
Console.WriteLine(attribute.Value);

【讨论】:

    【解决方案2】:

    使用我的自定义属性:

    [AttributeUsage(AttributeTargets.Method)]
    public class AttributeCustom : Attribute
    {
        public string MyPropertyAttribute { get; private set; }
    
        public AttributeCustom(string myproperty)
        {
            this.MyPropertyAttribute = myproperty;
        }
    }
    

    我用他的值创建了一个获取属性的方法:

    public static AttributeCustom GetAttributeCustom<T>(string method) where T : class
    {
        try
        {
            return ((AttributeCustom)typeof(T).GetMethod(method).GetCustomAttributes(typeof(AttributeCustom), false).FirstOrDefault());
        }
        catch(SystemException)
        {
            return null;
        }
    }
    

    带有示例类(必须不是静态的,因为 T 是通用的)

    public class MyClass
    {
        [AttributeCustom("value test attribute")])
        public void MyMethod() 
        {
            //...
        }
    }
    

    用法:

    var customAttribute = GetAttributeCustom<MyClass>("MyMethod");
    if (customAttribute != null)
    {
        Console.WriteLine(customAttribute.MyPropertyAttribute);
    }
    

    【讨论】:

      【解决方案3】:

      将对象投射到MethodTestingAttibute

      object actual = method.Invoke(obj, null);
      
      MethodTestingAttibute attribute = (MethodTestingAttibute)method.GetCustomAttributes(typeof(MethodTestAttribute), true)[0];
      string expected = attribute.Value;
      
      bool areEqual = string.Equals(expected, actual != null ? actual.ToString() : null, StringComparison.Ordinal);
      

      【讨论】:

        【解决方案4】:

        要获取属性属性的值,只需将 GetCustomAttributes() 返回的对象进行转换:

        {
            string val;
            object[] atts = method.GetCustomAttributes(typeof(MethodTestAttibute), true);
            if (atts.Length > 0)
               val = (atts[0] as MethodTestingAttibute).Value;
        }
        

        【讨论】:

          【解决方案5】:

          死灵术。
          对于那些仍然需要维护 .NET 2.0,或者想要在没有 LINQ 的情况下进行维护的人:

          public static object GetAttribute(System.Reflection.MemberInfo mi, System.Type t)
          {
              object[] objs = mi.GetCustomAttributes(t, true);
          
              if (objs == null || objs.Length < 1)
                  return null;
          
              return objs[0];
          }
          
          
          
          public static T GetAttribute<T>(System.Reflection.MemberInfo mi)
          {
              return (T)GetAttribute(mi, typeof(T));
          }
          
          
          public delegate TResult GetValue_t<in T, out TResult>(T arg1);
          
          public static TValue GetAttributValue<TAttribute, TValue>(System.Reflection.MemberInfo mi, GetValue_t<TAttribute, TValue> value) where TAttribute : System.Attribute
          {
              TAttribute[] objAtts = (TAttribute[])mi.GetCustomAttributes(typeof(TAttribute), true);
              TAttribute att = (objAtts == null || objAtts.Length < 1) ? default(TAttribute) : objAtts[0];
              // TAttribute att = (TAttribute)GetAttribute(mi, typeof(TAttribute));
          
              if (att != null)
              {
                  return value(att);
              }
              return default(TValue);
          }
          

          示例用法:

          System.Reflection.FieldInfo fi = t.GetField("PrintBackground");
          wkHtmlOptionNameAttribute att = GetAttribute<wkHtmlOptionNameAttribute>(fi);
          string name = GetAttributValue<wkHtmlOptionNameAttribute, string>(fi, delegate(wkHtmlOptionNameAttribute a){ return a.Name;});
          

          或者在你的情况下只是

          MethodInfo mi = typeof(Vehicles).GetMethod("m1");
          string aValue = GetAttributValue<MethodTestingAttibute, string>(mi, a => a.Value);
          

          【讨论】:

            【解决方案6】:

            在此处查看代码http://msdn.microsoft.com/en-us/library/bfwhbey7.aspx

            摘录:

                    // Get the AClass type to access its metadata.
                    Type clsType = typeof(AClass);
                    // Get the type information for Win32CallMethod.
                    MethodInfo mInfo = clsType.GetMethod("Win32CallMethod");
                    if (mInfo != null)
                    {
                        // Iterate through all the attributes of the method.
                        foreach(Attribute attr in
                            Attribute.GetCustomAttributes(mInfo)) {
                            // Check for the Obsolete attribute.
                            if (attr.GetType() == typeof(ObsoleteAttribute))
                            {
                                Console.WriteLine("Method {0} is obsolete. " +
                                    "The message is:",
                                    mInfo.Name);
                                Console.WriteLine("  \"{0}\"",
                                    ((ObsoleteAttribute)attr).Message);
                            }
            
                            // Check for the Unmanaged attribute.
                            else if (attr.GetType() == typeof(UnmanagedAttribute))
                            {
                                Console.WriteLine(
                                    "This method calls unmanaged code.");
                                Console.WriteLine(
                                    String.Format("The Unmanaged attribute type is {0}.",
                                                  ((UnmanagedAttribute)attr).Win32Type));
                                AClass myCls = new AClass();
                                myCls.Win32CallMethod();
                            }
                        }
                    }
            

            【讨论】:

              猜你喜欢
              • 2011-07-19
              • 1970-01-01
              • 2021-06-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-05-03
              • 2015-09-28
              • 1970-01-01
              相关资源
              最近更新 更多