C#如何获得CallerMember的类型名称 [英] c# how to get Type name of a CallerMember

查看:1317
本文介绍了C#如何获得CallerMember的类型名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到了这个类

public class fooBase
{
    public List<MethodsWithCustAttribute> MethodsList;
    public bool fooMethod([CallerMemberName]string membername =""))
    {
        //This returns a value depending of type and method 
    } 
    public void GetMethods()
    {
        // Here populate MethodsList using reflection
    }
}

和这Attribue类

And This Attribue Class

// This attribute get from a database some things, then fooMethod check this attribute members 
public class CustomAttribute
{
    public string fullMethodPath;
    public bool someThing ; 
    public bool CustomAttribute([CallerMemberName]string membername ="")
    {
        fullMethodPath = **DerivedType** + membername 
        //  I need here to get the type of membername parent. 
        //  Here I want to get CustClass, not fooBase

    }
}

然后我有这个

public class CustClass : fooBase
{
     [CustomAttribute()]
     public string method1()
     {
         if (fooMethod())
         {
             ....
         }
     }
}

我需要CallerMember的类型名称,有什么样[ CallerMemberName]来获得主叫类所有者的类型?

I need the Type name of the CallerMember, there is something like [CallerMemberName] to get the Type of class owner of the Caller ?

推荐答案

这CompilerServices提供的信息在我看来是摆脱调用方法的类型太少。
你可以做的是使用堆栈跟踪)来查找调用方法(使用实现getMethod()),并使用获得的类型反射从那里。
结果考虑以下几点:

The information that CompilerServices provides is too little in my opinion to get the type from the calling method. What you could do is use StackTrace (see) to find the calling method (using GetMethod()) and get the type using Reflection from there.
Consider the following:

using System.Runtime.CompilerServices;

public class Foo {
    public void Main() {
        what();
    }

    public void what() {
        Bar.GetCallersType();
    }

    public static class Bar {

        [MethodImpl(MethodImplOptions.NoInlining)]  //This will prevent inlining by the complier.
        public static void GetCallersType() {
            StackTrace stackTrace = new StackTrace(1, false); //Captures 1 frame, false for not collecting information about the file
            var type = stackTrace.GetFrame(1).GetMethod().DeclaringType;
            //this will provide you typeof(Foo);
        }
    }
}



的通知 - 作为@Jay在评论中说,这可能是相当昂贵的,但它确实把工作做好。结果

Notice - As @Jay said in the comments, it might be pretty expensive but it does the work well.

我发现几个比较性能arcticles的,并且它确实是horrbily昂贵比较反射这也被认为不是最好的结果,请参见:的 [1] [2 ]

I found couple of arcticles comparing the performance, and it is indeed horrbily expensive comparing to Reflection which is also considered not the best.
See: [1] [2]

因此,在深入看看后堆栈跟踪,这的确不是安全使用它,甚至昂贵。结果
因为每个将要调用的方法将被打上一个 [ CustomAttribute()] ,可以收集包含它在静态列表中的所有方法。

So after a look in depth on StackTrace, it is indeed not safe to use it and even expensive.
Since every method that will be called is going to be marked with a [CustomAttribute()], it is possible to collect all methods that contains it in a static list.

public class CustomAttribute : Attribute {
    public static List<MethodInfo> MethodsList = new List<MethodInfo>();
    static CustomAttribute() {
        var methods = Assembly.GetExecutingAssembly() //Use .GetCallingAssembly() if this method is in a library, or even both
                  .GetTypes()
                  .SelectMany(t => t.GetMethods())
                  .Where(m => m.GetCustomAttributes(typeof(CustomAttribute), false).Length > 0)
                  .ToArray();
        MethodsList = new List<MethodInfo>(methods);
    }

    public string fullMethodPath;
    public bool someThing;

    public  CustomAttribute([CallerMemberName] string membername = "") {
        var method = MethodsList.FirstOrDefault(m=>m.Name == membername);
        if (method == null || method.DeclaringType == null) return; //Not suppose to happen, but safety comes first
        fullMethodPath = method.DeclaringType.Name + membername; //Work it around any way you want it
        //  I need here to get the type of membername parent. 
        //  Here I want to get CustClass, not fooBase
    }
}

玩弄这种方法适合您的精确需求。

Play around with this approach to fit your precise need.

这篇关于C#如何获得CallerMember的类型名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆