C# dotnet core 中同一属性的多个方法的自定义属性声明
Custom attributes declaration of multiple methods for the same attribute in C# dotnet core
正如我在其他问题中提到的 , and based on the answer given by @Abdul Rahman 我能够 call/reject 使用以下代码调用属性下的函数:
using System;
using System.Linq; // for using Where
using System.Reflection;
namespace attribute
{
public class Program
{
public static int Main(string[] args)
{
var customAttributes = (MyCustomAttribute[])((typeof(Foo).GetTypeInfo())
.DeclaredMethods.Where(x => x.Name == "fn") // my question about this
.FirstOrDefault())
.GetCustomAttributes(typeof(MyCustomAttribute), true);
if (customAttributes.Length > 0)
{
var myAttribute = customAttributes[0];
string value = myAttribute.SomeProperty;
if (value == "bar")
Foo.fn();
else
Console.WriteLine("The attribute parameter is not as required");
}
return 0;
}
}
}
到目前为止,Attribute 和 Foo 类 很简单,因为我正处于学习阶段:
[AttributeUsage(AttributeTargets.All)]
public class MyCustomAttribute : Attribute
{
public string SomeProperty { get; set; }
}
public class Foo
{
[MyCustom(SomeProperty = "bar")]
internal static void fn()
{
Console.WriteLine("a function in a class");
}
[MyCustom(SomeProperty = "bar")]
internal static void fn2()
{
Console.WriteLine("another function in the same class");
}
}
public class Foo2
{
[MyCustom(SomeProperty = "bar")]
internal static void fn2()
{
Console.WriteLine("another function in a nother class");
}
}
我的问题是关于 .DeclaredMethods.Where(x => x.Name == "fn")
我是否需要为我添加的每个功能重复相同的操作,或者有一个简单的扩展可以为我做这个,我的目标就是这样,我需要检查属性参数,如果和我的输入匹配,我需要启动属性下的函数,如果不匹配,函数不会运行。谢谢
更新
将示例代码添加到 ideone.com 以便于检查
http://ideone.com/E9uL6r
可以准备f.e。您需要的函数名称集合:
var targetFns = new HashSet<string>(new[] { "fn", "fn2","fn3" });
...
.DeclaredMethods.Where(x => targetFns.Contains(x.Name));
如果 targetFns
中的项目数量较少,您可以只使用数组而不是 HashSet
。
所以,总结一下:
var method = (typeof(Foo).GetTypeInfo())
.DeclaredMethods.Where(x => targetFns.Contains(x.Name)).FirstOrDefault();
if (method == null) return;
var customAttributes = (MyCustomAttribute[])method.GetCustomAttributes(
typeof(MyCustomAttribute), true);
...
if (value == "bar")
method.Invoke(null, null);
我会四处做一个像这样的通用方法
public static void CallMethod<T>(string methodName, string value)
{
var method = typeof(T).GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.NonPublic);
if (method == null)
{
Console.WriteLine("The method not found");
return;
}
foreach (var myAttribute in method.GetCustomAttributes<MyCustomAttribute>())
{
if (myAttribute.SomeProperty == value)
{
method.Invoke(null, null);
}
else
{
Console.WriteLine("The attribute parameter is not as required");
}
}
}
你可以调用哪个
CallMethod<Foo>("fn", "bar");
我假设您的方法是静态的。所以他们不需要对象实例。
static void ExecuteFunction(Type T,string functionName, string Value)
{
MethodInfo m = ((T.GetTypeInfo()).DeclaredMethods.Where(x => x.Name == functionName).FirstOrDefault());
//var customAttributes = (MyCustomAttribute[])((T.GetTypeInfo()).DeclaredMethods.Where(x => x.Name == functionName).FirstOrDefault()).GetCustomAttributes(typeof(MyCustomAttribute), true);
var customAttributes = (MyCustomAttribute[])(m.GetCustomAttributes(typeof(MyCustomAttribute), true));
if (customAttributes.Length > 0)
{
var myAttribute = customAttributes[0];
string value = myAttribute.SomeProperty;
// TODO: Do something with the value
Console.WriteLine(value);
if (value == Value)
{
m.Invoke(null, null);
}
else
Console.WriteLine("Unauthorized");
}
}
& 执行为
ExecuteFunction(typeof(Foo), "fn", "bar");
编辑:
根据您的错误更新解决方案:
您正在检查字符串。您应该根据字符串获取 class,然后检查其中的方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Reflection;
namespace ConsoleApp1Core
{
[AttributeUsage(AttributeTargets.All)]
public class MyCustomAttribute : Attribute
{
public string SomeProperty { get; set; }
}
public class Foo
{
[MyCustom(SomeProperty = "bar")]
internal static void fn()
{
Console.WriteLine("a function in a class");
}
[MyCustom(SomeProperty = "bar")]
internal static void fn2()
{
Console.WriteLine("another function in the same class");
}
}
public class Foo2
{
[MyCustom(SomeProperty = "bar")]
internal static void fn2()
{
Console.WriteLine("another function in a nother class");
}
}
public class Program
{
public static int Main(string[] args)
{
var targetClasses = new HashSet<string>(new[] { "ConsoleApp1Core.Foo", "ConsoleApp1Core.Foo2" });
var targetFns = new HashSet<string>(new[] { "fn", "fn2", "fn3" });
var j = 0;
foreach (var target in targetClasses)
{
Console.WriteLine("_class round {0}", j++);
var i = 0;
foreach (var fn in targetFns)
{
Console.WriteLine("fn round {0}", i++);
Type t = Type.GetType(target);
var method = (t.GetTypeInfo()) // (typeof(Foo).GetTypeInfo())
.DeclaredMethods.Where(x => x.Name == fn).FirstOrDefault();
if (method != null) //return 0;
{
var customAttributes = (MyCustomAttribute[])method
.GetCustomAttributes(typeof(MyCustomAttribute), true);
if (customAttributes.Length > 0)
{
var myAttribute = customAttributes[0];
string value = myAttribute.SomeProperty;
if (value == "bar")
method.Invoke(null, null);
// Foo.fn();;
else
Console.WriteLine("The attribute parameter is not as required");
}
}
else
{
Console.WriteLine("Method not found");
}
}
}
return 0;
}
}
}
正如我在其他问题中提到的
using System;
using System.Linq; // for using Where
using System.Reflection;
namespace attribute
{
public class Program
{
public static int Main(string[] args)
{
var customAttributes = (MyCustomAttribute[])((typeof(Foo).GetTypeInfo())
.DeclaredMethods.Where(x => x.Name == "fn") // my question about this
.FirstOrDefault())
.GetCustomAttributes(typeof(MyCustomAttribute), true);
if (customAttributes.Length > 0)
{
var myAttribute = customAttributes[0];
string value = myAttribute.SomeProperty;
if (value == "bar")
Foo.fn();
else
Console.WriteLine("The attribute parameter is not as required");
}
return 0;
}
}
}
到目前为止,Attribute 和 Foo 类 很简单,因为我正处于学习阶段:
[AttributeUsage(AttributeTargets.All)]
public class MyCustomAttribute : Attribute
{
public string SomeProperty { get; set; }
}
public class Foo
{
[MyCustom(SomeProperty = "bar")]
internal static void fn()
{
Console.WriteLine("a function in a class");
}
[MyCustom(SomeProperty = "bar")]
internal static void fn2()
{
Console.WriteLine("another function in the same class");
}
}
public class Foo2
{
[MyCustom(SomeProperty = "bar")]
internal static void fn2()
{
Console.WriteLine("another function in a nother class");
}
}
我的问题是关于 .DeclaredMethods.Where(x => x.Name == "fn")
我是否需要为我添加的每个功能重复相同的操作,或者有一个简单的扩展可以为我做这个,我的目标就是这样,我需要检查属性参数,如果和我的输入匹配,我需要启动属性下的函数,如果不匹配,函数不会运行。谢谢
更新 将示例代码添加到 ideone.com 以便于检查 http://ideone.com/E9uL6r
可以准备f.e。您需要的函数名称集合:
var targetFns = new HashSet<string>(new[] { "fn", "fn2","fn3" });
...
.DeclaredMethods.Where(x => targetFns.Contains(x.Name));
如果 targetFns
中的项目数量较少,您可以只使用数组而不是 HashSet
。
所以,总结一下:
var method = (typeof(Foo).GetTypeInfo())
.DeclaredMethods.Where(x => targetFns.Contains(x.Name)).FirstOrDefault();
if (method == null) return;
var customAttributes = (MyCustomAttribute[])method.GetCustomAttributes(
typeof(MyCustomAttribute), true);
...
if (value == "bar")
method.Invoke(null, null);
我会四处做一个像这样的通用方法
public static void CallMethod<T>(string methodName, string value)
{
var method = typeof(T).GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.NonPublic);
if (method == null)
{
Console.WriteLine("The method not found");
return;
}
foreach (var myAttribute in method.GetCustomAttributes<MyCustomAttribute>())
{
if (myAttribute.SomeProperty == value)
{
method.Invoke(null, null);
}
else
{
Console.WriteLine("The attribute parameter is not as required");
}
}
}
你可以调用哪个
CallMethod<Foo>("fn", "bar");
我假设您的方法是静态的。所以他们不需要对象实例。
static void ExecuteFunction(Type T,string functionName, string Value)
{
MethodInfo m = ((T.GetTypeInfo()).DeclaredMethods.Where(x => x.Name == functionName).FirstOrDefault());
//var customAttributes = (MyCustomAttribute[])((T.GetTypeInfo()).DeclaredMethods.Where(x => x.Name == functionName).FirstOrDefault()).GetCustomAttributes(typeof(MyCustomAttribute), true);
var customAttributes = (MyCustomAttribute[])(m.GetCustomAttributes(typeof(MyCustomAttribute), true));
if (customAttributes.Length > 0)
{
var myAttribute = customAttributes[0];
string value = myAttribute.SomeProperty;
// TODO: Do something with the value
Console.WriteLine(value);
if (value == Value)
{
m.Invoke(null, null);
}
else
Console.WriteLine("Unauthorized");
}
}
& 执行为
ExecuteFunction(typeof(Foo), "fn", "bar");
编辑: 根据您的错误更新解决方案: 您正在检查字符串。您应该根据字符串获取 class,然后检查其中的方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Reflection;
namespace ConsoleApp1Core
{
[AttributeUsage(AttributeTargets.All)]
public class MyCustomAttribute : Attribute
{
public string SomeProperty { get; set; }
}
public class Foo
{
[MyCustom(SomeProperty = "bar")]
internal static void fn()
{
Console.WriteLine("a function in a class");
}
[MyCustom(SomeProperty = "bar")]
internal static void fn2()
{
Console.WriteLine("another function in the same class");
}
}
public class Foo2
{
[MyCustom(SomeProperty = "bar")]
internal static void fn2()
{
Console.WriteLine("another function in a nother class");
}
}
public class Program
{
public static int Main(string[] args)
{
var targetClasses = new HashSet<string>(new[] { "ConsoleApp1Core.Foo", "ConsoleApp1Core.Foo2" });
var targetFns = new HashSet<string>(new[] { "fn", "fn2", "fn3" });
var j = 0;
foreach (var target in targetClasses)
{
Console.WriteLine("_class round {0}", j++);
var i = 0;
foreach (var fn in targetFns)
{
Console.WriteLine("fn round {0}", i++);
Type t = Type.GetType(target);
var method = (t.GetTypeInfo()) // (typeof(Foo).GetTypeInfo())
.DeclaredMethods.Where(x => x.Name == fn).FirstOrDefault();
if (method != null) //return 0;
{
var customAttributes = (MyCustomAttribute[])method
.GetCustomAttributes(typeof(MyCustomAttribute), true);
if (customAttributes.Length > 0)
{
var myAttribute = customAttributes[0];
string value = myAttribute.SomeProperty;
if (value == "bar")
method.Invoke(null, null);
// Foo.fn();;
else
Console.WriteLine("The attribute parameter is not as required");
}
}
else
{
Console.WriteLine("Method not found");
}
}
}
return 0;
}
}
}