对不起,如果这是一个愚蠢的菜鸟问题,请温柔地对待我,我正在努力学习......
我想测试模型和控制器之类的属性方法。主要是为了确保他们有正确的属性,即必需。但我也将它用作扩展方法和Lambdas的实验。
我想要的是一种方法,当被赋予某种东西时会看起来像
Controller controller = new Controller();
controller.MethodName(params).HasAttribute<AttributeName>();
稍微使用了扩展方法,但没有达到这个程度。我确信这应该很简单,但似乎无法使我的泛型等正确。
答案 0 :(得分:19)
也许您正在寻找这个:
Controller controller = new Controller();
bool ok = controller.GetMethod(c => c.MethodName(null, null))
.HasAttribute<AttributeName>();
这样编写它的好处是你有完全编译时间支持。到目前为止,所有其他解决方案都使用字符串文字来定义方法。
以下是GetMethod
和HasAttribute<T>
扩展方法的实现:
public static MethodInfo GetMethod<T>(this T instance,
Expression<Func<T, object>> methodSelector)
{
// Note: this is a bit simplistic implementation. It will
// not work for all expressions.
return ((MethodCallExpression)methodSelector.Body).Method;
}
public static MethodInfo GetMethod<T>(this T instance,
Expression<Action<T>> methodSelector)
{
return ((MethodCallExpression)methodSelector.Body).Method;
}
public static bool HasAttribute<TAttribute>(
this MemberInfo member)
where TAttribute : Attribute
{
return GetAttributes<TAttribute>(member).Length > 0;
}
public static TAttribute[] GetAttributes<TAttribute>(
this MemberInfo member)
where TAttribute : Attribute
{
var attributes =
member.GetCustomAttributes(typeof(TAttribute), true);
return (TAttribute[])attributes;
}
答案 1 :(得分:1)
我认为你无法完全按照你的描述实施。语句的MethodName(params)
部分实际上将执行该方法,返回方法返回的内容,而不是有关方法的信息。
您要做的是使用反射将MethodInfo
传入您的扩展程序。因此,您可能最终会得到类似的结果:
controller.GetType().GetMethod(methodName).HasAttribute<AttributeName>();
您可以通过封装GetType().GetMethod()
来简化控制器类上的单个扩展方法,如下所示:
controller.MethodHasAttribute(methodName, attributeName);
答案 2 :(得分:1)
使用扩展方法无法做到这一点,但这很接近:
public static class Program
{
static void Main(string[] args)
{
Controller c1 = new Controller();
Action a1 = c1.Method1;
Console.WriteLine(a1.HasAttribute<Controller.TestAttribute>());
}
public static bool HasAttribute<T>(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()
{
}
}
答案 3 :(得分:1)
<强>用法:强>
bool hasAttribute = controller.HasMethodAttribute<TestAttribute>( "Test" )
<强>扩展:强>
public static bool HasMethodAttribute<TAttribute>( 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 ;
}
答案 4 :(得分:0)
您可以通过执行以下操作来检查方法是否具有特定属性:
typeof(Controller).GetMethod("MethodName").GetAttributes<AttributeName>().Any();
就扩展方法本身而言,如果您正在寻找Controller类型的扩展方法,那么如何:
public static bool HasAttribute<A>(this Controller controller, string methodName)
{
return controller.GetType().GetMethod(methodName).GetCustomAttributes(typeof(A), true).Any();
}
请记住,在实例上调用扩展方法,因此要使用它,您仍需要一个Controller实例:
var controller = new Controller();
Assert.IsTrue(controller.HasAttribute<AttributeName>("Method1"));
答案 5 :(得分:-1)
您正在寻找Reflection类 - 它允许您检查传递的对象。
但坦率地说,除了学习练习之外,这就是Interfaces的存在,如果你想在模型中有一个名为Required的字段,或者在控制器中有一个名为IsRequired的方法,而不是在接口中实现,并要求实现接口
特别是对于属性,请参阅here:
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);
}
}