随着自定义属性和反射的大量学习曲线,我似乎仍然在苦苦挣扎。任何人都可以帮我解决这个问题吗?
基本上我想根据它的属性调用一个方法。
这是装饰方法的CustomAttribute(它只是一个方法): 的 [ControllerName(名称="博客&#34)]
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;
}
同样,如果可能,我想通过属性获取方法。
真的希望得到一些帮助。
///编辑 对不起,我在代码中添加了注释来说明问题。 基本上我想:
我不想按方法名称获取方法。
此致
答案 0 :(得分:1)
代码示例
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" }
- 参数数组。答案 1 :(得分:1)
一个简单的例子是:
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
周期简单和线性,并显示应该完成的所有其他检查。