这是C#4.0。
我有一个类WeakReference
存储Action
的类:
public class LoremIpsum
{
private Dictionary<Type, List<WeakReference>> references = new Dictionary<Type, List<WeakReference>>();
public void KeepReference<T>(Action<T> action)
{
if (this.references.ContainsKey(typeof(T)))
{
this.references[typeof(T)].Add(new WeakReference(action));
}
else
{
this.references.Add(typeof(T), new List<WeakReference> { new WeakReference(action) });
}
}
}
这个类有另一个允许执行稍后传递给它的Action
的方法,但在这个问题上它并不重要。
我以这种方式使用这个类:
public class Foobar
{
public Bar Bar { get; set; }
public void Foo(LoremIpsum ipsum)
{
ipsum.KeepReference<Bar>((b) => { this.Bar = b; });
ipsum.KeepReference<Bar>(this.Whatever);
}
public void Whatever(Bar bar)
{
// Do anything, for example...:
this.Bar = bar
}
}
Bar
是我申请中的第三堂课。
我的问题:
在KeepReference
方法中,我如何知道参数中传递的Action
是指匿名方法(this.Bar = b;
)还是具体方法( this.Whatever
)?
我检查了action
的属性。我在action
类IsAbstract
(例如IsAnonymous
)上找不到任何属性。基础类型是MethodInfo
这是有道理的,因为在编译后我可以在ildasm中看到匿名方法“成为”Foobar
上的常规方法。在ildasm我也可以看到匿名方法不是一个完整的粉红色正方形,而是一个被粉红色包围的白色方块,在它的定义中,它调用了一些CompilerServices类,但我不知道如何在C#中利用它。我确信有可能了解action
的真实性质。我错过了什么?
答案 0 :(得分:3)
为了在这个问题上得到“接受”的答案,我按照MichaelKjörling在我关于我的问题的第一条评论中给出的链接去了。
if (action.Target.GetType().GetMethods().Where(method => method.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Any()).Contains(action.Method))
{
// ...
}
答案 1 :(得分:2)
编译器生成的方法的名称将始终带有角度括号,如下所示
Void <Main>b__0()
所以为什么不只是获取名称,看看它是否有角度括号。
Action someaction = () => Console.Write("test");
string methodName= RuntimeReflectionExtensions.GetMethodInfo(someaction).ToString();
if(methodName.Contains("<"))
Console.write("anonymous");
或者您可以使用与正则表达式更好的模式匹配