C#用于检查属性的扩展方法

对不起,如果这是一个愚蠢的菜鸟问题,请温柔地对待我,我正在努力学习……

我想测试模型和控制器之类的属性方法。 主要是为了确保他们有正确的属性,即必需。 但我也将它用作扩展方法和Lambdas的实验。

我想要的是一种方法,当被称赞时看起来有点像

Controller controller = new Controller(); controller.MethodName(params).HasAttribute(); 

我尝试了一些扩展方法,但没有达到这个程度。我确信这应该很简单,但似乎无法使我的generics等正确。

也许你正在寻找这个:

 Controller controller = new Controller(); bool ok = controller.GetMethod(c => c.MethodName(null, null)) .HasAttribute(); 

像这样编写它的好处是你有完全编译时间支持。 到目前为止,所有其他解决方案都使用字符串文字来定义方法。

以下是GetMethodHasAttribute扩展方法的实现:

 public static MethodInfo GetMethod(this T instance, Expression> methodSelector) { // Note: this is a bit simplistic implementation. It will // not work for all expressions. return ((MethodCallExpression)methodSelector.Body).Method; } public static MethodInfo GetMethod(this T instance, Expression> methodSelector) { return ((MethodCallExpression)methodSelector.Body).Method; } public static bool HasAttribute( this MemberInfo member) where TAttribute : Attribute { return GetAttributes(member).Length > 0; } public static TAttribute[] GetAttributes( this MemberInfo member) where TAttribute : Attribute { var attributes = member.GetCustomAttributes(typeof(TAttribute), true); return (TAttribute[])attributes; } 

我认为你无法完全按照你的描述实施。 语句的MethodName(params)部分实际上将执行该方法,返回方法返回的任何内容,而不是有关该方法的信息。

您要做的是使用reflection将MethodInfo传递到您的扩展类中。 所以不是你的例子,你可能会得到类似的东西:

  controller.GetType().GetMethod(methodName).HasAttribute(); 

您可以通过封装GetType().GetMethod()来简化控制器类上的单个扩展方法,如下所示:

  controller.MethodHasAttribute(methodName, attributeName); 

使用扩展方法无法做到这一点,但这很接近:

 public static class Program { static void Main(string[] args) { Controller c1 = new Controller(); Action a1 = c1.Method1; Console.WriteLine(a1.HasAttribute()); } public static bool HasAttribute(this Action method) { return method.Method.GetCustomAttributes(typeof(T), false).Any(); } } class Controller { [AttributeUsage(AttributeTargets.Method)] public class TestAttribute : System.Attribute { } [Test()] public void Method1() { } } 

用法:

 bool hasAttribute = controller.HasMethodAttribute( "Test" ) 

延期:

 public static bool HasMethodAttribute( this object obj, string methodName ) { Type type = obj.GetType(); MethodInfo method = type.GetMethod( methodName ); if( method == null ) { throw new ArgumentException( string.Format( "Method '{0}' not found on object '{1}'", methodName, type.Name ) ); } return method.GetCustomAttributes( typeof( TAttribute ), true ).Length > 0 ; } 

您可以通过执行以下操作来检查方法是否具有特定属性:

 typeof(Controller).GetMethod("MethodName").GetAttributes().Any(); 

就扩展方法本身而言,如果您正在寻找Controller类型的扩展方法,那么这样的事情如何:

 public static bool HasAttribute(this Controller controller, string methodName) { return controller.GetType().GetMethod(methodName).GetCustomAttributes(typeof(A), true).Any(); } 

请记住,在实例上调用扩展方法,因此要使用它,您仍需要一个Controller实例:

 var controller = new Controller(); Assert.IsTrue(controller.HasAttribute("Method1")); 

您正在寻找Reflection类 – 它允许您检查传递的对象。

但坦率地说,除了学习练习之外,这就是接口的存在,如果你希望在模型中有一个名为Required的字段,或者在控制器中使用一个名为IsRequired的方法,而不是在接口中实现并要求实现接口。

具体针对属性请参见此处 :

 Type t = something; System.Console.WriteLine("Author information for {0}", t); System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t); // reflection foreach (System.Attribute attr in attrs) { if (attr is Author) { Author a = (Author)attr; System.Console.WriteLine(" {0}, version {1:f}", a.GetName(), a.version); } }