Давайте сделаем короткий тест:
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Reflection;
namespace TestAttrs {
public abstract class BaseAttribute : Attribute {
public string text;
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class MultipleInheritedAttribute : BaseAttribute { }
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class MultipleNonInheritedAttribute : BaseAttribute { }
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class SingleInheritedAttribute : BaseAttribute { }
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class SingleNonInheritedAttribute : BaseAttribute { }
public class BaseClass {
[MultipleInherited(text = "MultipleInheritedBase")]
[MultipleNonInherited(text = "MultipleNonInheritedBase")]
[SingleInherited(text = "SingleInheritedBase")]
[SingleNonInherited(text = "SingleNonInheritedBase")]
public virtual void Method() { ; }
}
public class DerivedClass : BaseClass {
[MultipleInherited(text = "MultipleInheritedDerived")]
[MultipleNonInherited(text = "MultipleNonInheritedDerived")]
[SingleInherited(text = "SingleInheritedDerived")]
[SingleNonInherited(text = "SingleNonInheritedDerived")]
public override void Method() {
base.Method();
}
}
[TestClass]
public class AttributesTest {
[TestMethod]
public void TestAttributes() {
MemberInfo mi = typeof(DerivedClass).GetMember("Method")[0];
object[] attrs = mi.GetCustomAttributes(true);
string log = "";
foreach(BaseAttribute attr in attrs) {
log += attr.text+"|";
}
Assert.AreEqual("MultipleInheritedDerived|SingleInheritedDerived|SingleNonInheritedDerived|MultipleNonInheritedDerived|MultipleInheritedBase|", log);
}
}
}
Как видите, если атрибут помечен Inherted=true
, он будет возвращен для производных классов, но если унаследованный метод помечен тем же атрибутом - он будет подавлен, если AllowMultiple=false
.
Итак, в нашем тесте строка журнала содержит как «MultipleInheritedDerived», так и «MultipleInheritedBase», но не «SingleInheritedBase».
Итак, отвечая на ваш вопрос - какой смысл? Эта комбинация позволяет вам иметь базовый контроллер с виртуальным методом, который вы можете переопределить, не беспокоясь об атрибуте (он будет взят из базового метода), но в то же время иметь возможность переопределить его, если хотите. HttpPostAttribute не является хорошим примером, потому что он не имеет параметров, но другие атрибуты могут извлечь выгоду из таких настроек.
Также обратите внимание, что атрибуты, потребляющие код:
object[] attrs = mi.GetCustomAttributes(true);
указывает, что он заинтересован в унаследованных атрибутах. Если напишите
object[] attrs = mi.GetCustomAttributes(false);
тогда результат будет содержать 4 атрибута независимо от настроек их использования. Таким образом, разработчик может игнорировать настройку использования унаследованных атрибутов.