C#dotnet核心中相同属性的多个方法的自定义属性声明

时间:2016-10-18 05:17:51

标签: c# extension-methods .net-core custom-attributes

正如我在其他问题here中提到的那样,基于@Abdul Rahman给出的答案,我能够使用以下代码调用/拒绝属性下的函数调用:

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;
    }
  }
}

到目前为止,属性和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

3 个答案:

答案 0 :(得分:0)

你可以准备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);

答案 1 :(得分:0)

我会去制作像这样的通用方法

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");

答案 2 :(得分:0)

我假设你的方法是静态的。所以他们不需要对象实例。

 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");

修改: 根据您的错误更新了解决方案: 你正在检查字符串。你应该根据字符串&amp;获得课程。然后检查其中的方法。

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;
        }
    }
}