如何使用属性'方法内的成员

时间:2017-02-01 09:24:23

标签: c# attributes

我创建了名为someAttribute的自定义属性 它有一个名为Skip的布尔成员:

public class someAttribute : Attribute
{
    public bool Skip { get; set; }
}

Main我使用方法Skip的值true初始化了成员foo()

接下来,我调用的函数foo()具有属性[someAttribute()],我想检查成员Skip是否已初始化:

[someAttribute()]
private static int foo()
{
    if(Skip)
     {
         return 0;
     }

    return 1;
} 

我收到了错误" 名称' Skip'在当前上下文中不存在"。
enter image description here

如何检查使用此属性的方法内的属性成员?

我的完整代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace ConsoleApplication1
{
    class ProgramTest
    {
        [someAttribute()]
        private static int foo()
        {
            if(Skip)
             {
                 return 0;
             }

            return 1;
        }

        public class someAttribute : Attribute
        {
            public bool Skip { get; set; }
        }

        public static void initAttributes()
        {
            var methods = Assembly.GetExecutingAssembly().GetTypes().SelectMany(t => t.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static))
           .Where(method => Attribute.IsDefined(method, typeof(someAttribute)));

            foreach (MethodInfo methodInfo in methods)
            {
                IEnumerable<someAttribute> SomeAttributes = methodInfo.GetCustomAttributes<someAttribute>();
                foreach (var attr in SomeAttributes)
                {
                    attr.Skip = true;
                }
            }
        }
        static void Main(string[] args)
        {
            initAttributes();
            int num = foo();
        }
     }
 }

修改
我添加BindingFlags.Static以使refelction获取静态函数foo()

2 个答案:

答案 0 :(得分:2)

您可以使用以下内容获取属性:

[someAttribute()]
private static int foo()
{
    if (GetCurrentMethodAttribute<someAttribute>().Skip)
    {
        return 0;
    }
    return 1;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static T GetCurrentMethodAttribute<T>() where T : Attribute
{
    return (T)new StackTrace().GetFrame(1).GetMethod().GetCustomAttribute(typeof(T));
}

无论如何,在您的initAttributes()方法中,当您执行Assembly.GetExecutingAssembly().GetTypes().SelectMany时,您没有获得foo方法,因为它是static,所以您也应该使用BindingFlags.Static

另外,you cannot set an attribute value at runtime,因此当您检索属性时,initAttributes所做的更改将不会被“看到”(因此Skip属性将为false

答案 1 :(得分:1)

您可以使用反射来实现此目的:

if proj.class.name == 'String'
        project = Project.create title: proj
      elsif proj.class.name == 'Array'

这会获得case proj when String # proj is a String when Array # proj is an Array end 的{​​{1}},并检查该方法是否包含 [someAttribute()] private static int foo() { if (typeof(ProgramTest).GetMethod(nameof(foo)). GetCustomAttribute<someAttribute>()?.Skip ?? false) return 0; return 1; } 。如果是,则检查该属性实例的MethodInfo属性。

在您的情况下,foo需要更多参数,因为someAttributeSkipGetMethod()。如果您有多个foo重载,则还需要指定参数类型:

private

(注意:在之前的编辑中,我建议使用static,但显然这不适用于非空方法。)