Csharp/C#教程:c#如何获取CallerMember的类型名称分享


c#如何获取CallerMember的类型名称

我上了这堂课

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

而这个属性类

 // 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的Type名称,有类似[CallerMemberName]的东西来获取Caller的类所有者?

它并非万无一失,但.NET的约定是每个文件有一种类型,并且命名文件与类型相同。 我们的工具也倾向于强制执行此约定,即Resharper和Visual Studio。

因此,从文件路径推断类型名称应该是合理的。

 public class MyClass { public void MyMethod([CallerFilePath]string callerFilePath = null, [CallerMemberName]string callerMemberName = null) { var callerTypeName = Path.GetFileNameWithoutExtension(callerFilePath); Console.WriteLine(callerTypeName); Console.WriteLine(callerMemberName); } } 

在我看来,CompilerServices提供的信息太少,无法从调用方法中获取类型。 你可以做的是使用StackTrace ( 请参阅 StackTrace )查找调用方法(使用GetMethod() )并从那里使用Reflection获取类型。
考虑以下:

 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在评论中所说的那样,它可能相当昂贵,但它确实很有效。

编辑:

我发现了几个比较性能的arcticle,与Reflection相比,它确实是非常昂贵的,而Reflection也被认为不是最好的。
见: [1] [2]

编辑2:

因此,在深入研究StackTrace ,使用它确实不安全甚至是昂贵的。
由于将调用的每个方法都将使用[CustomAttribute()]标记,因此可以在静态列表中收集包含它的所有方法。

 public class CustomAttribute : Attribute { public static List MethodsList = new List(); 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(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 } } 

使用这种方法来满足您的精确需求。

来电成员

当然,获取调用者成员名称在对象模型中不是“自然的”。 这就是C#工程师在编译器中引入CallerMemberName的原因。

真正的敌人是重复,基于堆栈的解决方法是低效的。

[CallerMemberName]允许获取信息而不会重复,也不会产生不良影响。

来电者类型

但是获取调用者成员类型 自然的,并且很容易获得而无需重复。

怎么做

fooMethod添加“caller”参数,不需要特殊属性。

  public bool fooMethod(object caller, [CallerMemberName]string membername = "") { Type callerType = caller.GetType(); //This returns a value depending of type and method return true; } 

并称之为:

 fooMethod(this); 

这回答了这个问题

你说

//这里我想获得CustClass,而不是fooBase

而这正是你将得到的。

其他不会炒的情况。

虽然这完全符合您的要求,但还有其他不同的情况,它不起作用。

这些情况下, [CallerMemberType]可能有意义。 然而,这些案例的解决方案主要是调用者源文件的本地解决方案,因此它们并不是一个大问题恕我直言。

上述就是C#学习教程:c#如何获取CallerMember的类型名称分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1251263.html

(0)
上一篇 2022年11月8日
下一篇 2022年11月8日

精彩推荐