none
关于C#中的System.AttributeUsageAttribute类 RRS feed

  • 问题

  • 请问System.AttributeUsageAttribute类中的Inherited属性到底是什么意思啊?如果是“是否可以被继承”的意思,那么下面的代码如何解释?

      [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
      public sealed class ValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter {
    

    这是MVC里面的代码,ValidateAntiForgeryTokenAttribute类是sealed的,指明不能被继承。那上面的属性

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    

    又是标记为Inherited=true,是否应该标记为false啊?

    请教?


    2010年12月20日 2:07

答案

  • Inherited = true 表示该 Atrribute 可以被继承应用了该 Attribute 的类型的派生类型所继承。如 System.SerializableAttribute 就是不可继承。也就是说,如果一个类型 A,使用了一个 Attribute B,那么如果类型 C 派生于类型 A,假设在 Attribute B 上有声明 Inherited = true,那么类型 C 会默认应用 Attribute B,否则类型 C 不会应用 Attribute B。
    Mark Zhou
    • 已标记为答案 陈书函 2010年12月22日 7:40
    2010年12月20日 7:15
  • 你好,

    如果你想判断Inherited属性是否真的起到了作用,你应该用反射去测试。

    我这里写了一段demo,你可以放到你的机器上去运行,并修改Inherited属性,看看输出的结果。在我下面这段代码中,我把Attribute的范围缩小到Method,并且在更改Inherited属性时,出现了不同的Attribute的继承关系。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    
    namespace AttrTest
    {
      class Program
      {
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
        public class MyAttribute : Attribute
        {
          private string regKey = "a12nf";
          public MyAttribute(string regKey)
          {
            if (this.regKey == regKey)
            {
              Console.WriteLine("Permitted to use this App");
            }
            else
            {
              Console.WriteLine("Not registered to use this App");
            }
          }
        }
    
        class useAttrib
        {
          [My("Larcolais")]
          public virtual string SayHello(string str)
          {
            return "1";
          }
        }
    
        class b : useAttrib
        {
          public override string SayHello(string str)
          {
            return base.SayHello(str);
          }
        }
    
        static void Main(string[] args)
        {
          useAttrib a = new useAttrib();
          Type typeA = a.GetType();
          MethodInfo mInfo = typeA.GetMethod("SayHello");
          Attribute[] attr1 = Attribute.GetCustomAttributes(mInfo);
    
    
          b bb = new b();
          Type typeB = bb.GetType();
          MethodInfo mInfo2 = typeB.GetMethod("SayHello");
          Attribute[] attr2 = Attribute.GetCustomAttributes(mInfo2);
    
          Console.ReadLine();
        }
      }
    }
    
    

     另外,你的那段代码中其实只是实现了类与类之间正常的一个继承关系。当子类中没有方法或者实现时,他会向上延伸去调用基类的方法。

    谢谢,

    Larcolais


    Larcolais Gong[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 陈书函 2010年12月22日 7:39
    2010年12月21日 13:10

全部回复

  • Inherited = true 表示该 Atrribute 可以被继承应用了该 Attribute 的类型的派生类型所继承。如 System.SerializableAttribute 就是不可继承。也就是说,如果一个类型 A,使用了一个 Attribute B,那么如果类型 C 派生于类型 A,假设在 Attribute B 上有声明 Inherited = true,那么类型 C 会默认应用 Attribute B,否则类型 C 不会应用 Attribute B。
    Mark Zhou
    • 已标记为答案 陈书函 2010年12月22日 7:40
    2010年12月20日 7:15
  • 您好!

    我按您的回复,做了下面这个Demo,可结果Inherited = false 也能应用子类。

    namespace MvcAppOne.Extendsions
    {
      using System;
      using System.Web.Mvc;
      using System.Web;
      using System.Text;
    
      [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
      public class MyFilterAttribute : FilterAttribute, IAuthorizationFilter
      {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
          if (filterContext == null)
          {
            throw new ArgumentNullException("filterContext");
          }
          throw new Exception("这是MyFilter引发的异常");
        }
      }
    
      public class TestAttribute : MyFilterAttribute
      {
    
      }
    
    
      public class OrdersController : Controller
      {
        [TestAttribute]
        public ActionResult Index()
        {
          return View();
        }
      }
    }
    

    运行http://localhost/Orders/Index ,会抛出异常“这是MyFilter引发的异常”。说明[TestAttribute]应用了该Attribute。

    请教?


    2010年12月20日 9:02
  • 你好,

    请注意mazhou的回复,如果你想继承attrbute,你需要把Inherited = ture

    如果你还有其他问题,请描述你的错误信息,并及时让我知道。

    谢谢,

    Larcolais


    Larcolais Gong[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2010年12月21日 1:51
  • @Larcolais Gong

    你好,我上面的例子说明Inherited = false也能继承。不能您是否这样认为?

    如果Inherited标记false,那么它标记的类应该是sealed的。


    2010年12月21日 2:08
  • 你好,

    如果你想判断Inherited属性是否真的起到了作用,你应该用反射去测试。

    我这里写了一段demo,你可以放到你的机器上去运行,并修改Inherited属性,看看输出的结果。在我下面这段代码中,我把Attribute的范围缩小到Method,并且在更改Inherited属性时,出现了不同的Attribute的继承关系。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    
    namespace AttrTest
    {
      class Program
      {
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
        public class MyAttribute : Attribute
        {
          private string regKey = "a12nf";
          public MyAttribute(string regKey)
          {
            if (this.regKey == regKey)
            {
              Console.WriteLine("Permitted to use this App");
            }
            else
            {
              Console.WriteLine("Not registered to use this App");
            }
          }
        }
    
        class useAttrib
        {
          [My("Larcolais")]
          public virtual string SayHello(string str)
          {
            return "1";
          }
        }
    
        class b : useAttrib
        {
          public override string SayHello(string str)
          {
            return base.SayHello(str);
          }
        }
    
        static void Main(string[] args)
        {
          useAttrib a = new useAttrib();
          Type typeA = a.GetType();
          MethodInfo mInfo = typeA.GetMethod("SayHello");
          Attribute[] attr1 = Attribute.GetCustomAttributes(mInfo);
    
    
          b bb = new b();
          Type typeB = bb.GetType();
          MethodInfo mInfo2 = typeB.GetMethod("SayHello");
          Attribute[] attr2 = Attribute.GetCustomAttributes(mInfo2);
    
          Console.ReadLine();
        }
      }
    }
    
    

     另外,你的那段代码中其实只是实现了类与类之间正常的一个继承关系。当子类中没有方法或者实现时,他会向上延伸去调用基类的方法。

    谢谢,

    Larcolais


    Larcolais Gong[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 陈书函 2010年12月22日 7:39
    2010年12月21日 13:10
  • 明白了,非常感谢!


    2010年12月22日 7:39