通过CustomAttribute获取方法,然后调用
本文关键字:然后 调用 方法 CustomAttribute 获取 通过 | 更新日期: 2023-09-27 17:51:04
随着对自定义属性和反射的大量学习曲线,我似乎仍然在挣扎。有人能帮我解决这个问题吗?
基本上我想调用一个基于它的属性的方法。
这是修饰一个方法的CustomAttribute(它只能是一个方法): [ControllerName (Name = "博客"))
public static string GetContent(string controllerName, string singleItemName = "")
{
string returnVal = null;
//Get the class type
Type thisType = typeof(ContentFacade);
//Get member info
System.Reflection.MemberInfo info = typeof(ContentFacade);
Loop through attributes
foreach (object attrib in info.GetCustomAttributes(true))
{
//if the attribute matches the param controller name
//then invoke
if (attrib == controllerName)
{
//Get the method by attribute not method name
//I dont want to get the method by MethodName
MethodInfo theMethod = thisType.GetMethod(controllerName);
//Return the value as it will be html for the end user
returnVal = (string)theMethod.Invoke(controllerName, null);
}
}
return returnVal;
}
同样,如果可能的话,我希望通过属性获得方法。
真的很期待在这方面得到一些帮助。
编辑///对不起,我在代码中添加了注释来说明这个问题。基本上我想:
- 通过controllerName == "blog"获取属性
- 通过属性获取方法并调用
我不想通过方法名来获取方法
认为,
一个简单的例子是:
public static string GetContent(Type type, string controllerName)
{
foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
{
ControllerNameAttribute controller = (ControllerNameAttribute)method.GetCustomAttribute(typeof(ControllerNameAttribute));
if (controller == null)
{
continue;
}
if (controller.Name != controllerName)
{
continue;
}
if (method.IsGenericMethod)
{
throw new InvalidOperationException();
}
if (method.GetParameters().Length != 0)
{
throw new InvalidOperationException();
}
if (method.ReturnType != typeof(string))
{
throw new InvalidOperationException();
}
string result = (string)method.Invoke(null, null);
return result;
}
throw new InvalidOperationException();
}
你可以这样使用:
string result = GetContent(typeof(Program), "blog");
其中Program
为方法所在的类。
请注意,正如所写的那样,这段代码只适用于static
方法。如果你想使用实例方法,把它改成:
public static string GetContent(object instance, string controllerName)
{
Type type = instance.GetType();
foreach (MethodInfo method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
{
ControllerNameAttribute controller = (ControllerNameAttribute)method.GetCustomAttribute(typeof(ControllerNameAttribute));
if (controller == null)
{
continue;
}
if (controller.Name != controllerName)
{
continue;
}
if (method.IsGenericMethod)
{
throw new InvalidOperationException();
}
if (method.GetParameters().Length != 0)
{
throw new InvalidOperationException();
}
if (method.ReturnType != typeof(string))
{
throw new InvalidOperationException();
}
string result = (string)method.Invoke(instance, null);
return result;
}
throw new InvalidOperationException();
}
一般情况下,两种方法都不检查给定controllerName
是否存在单一方法。它们只是执行找到的第一个。这是可能的,甚至检查,通常使用LINQ,但我想保持foreach
循环简单和线性,并显示所有其他检查应该做的。
代码示例
public class MyClass
{
[System.ComponentModel.DisplayName("my test method")]
public bool TestMethod(string input)
{
return input == "OK";
}
[System.ComponentModel.DisplayName("my second method")]
public string TestMethod2(string input)
{
return input;
}
public void Invoke(string displayName)
{
// attribute type we search
Type attributeType = typeof(System.ComponentModel.DisplayNameAttribute);
// find method
var methodInfo = (from e in this.GetType().GetMethods()
let attributes = e.GetCustomAttributes(attributeType).Cast<System.ComponentModel.DisplayNameAttribute>().ToArray()
where attributes.Length != 0 &&
attributes.Any(x => string.Equals(x.DisplayName, displayName, StringComparison.InvariantCultureIgnoreCase))
select e).FirstOrDefault();
if (methodInfo != null)
{
// method found
Console.WriteLine("Invoke {0} method: {1}", methodInfo.Name, methodInfo.Invoke(this, new object[] { "OK" }));
}
}
}
评论> -
this.GetType().GetMethods()
-获取所有方法,你可以通过BindingFlags
指定你想返回哪种方法。 -
e.GetCustomAttributes(typeof(System.ComponentModel.DisplayNameAttribute))
-获取指定类型的所有属性 -
methodInfo.Invoke(this, new object[] { "OK" })
-方法调用,this
-类实例(null
为静态方法),new object[] { "OK" }
-参数数组。