This is C# 4.0.
I have a class that stores WeakReference
s on some Action
s like that:
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) });
}
}
}
This class has another method allowing to execute the Action
s passed to it later but it's of little importance in this question.
and I consume this class this way:
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
being a third class in my application.
My question:
In the KeepReference
method, how can I know if the Action
passed in parameter refers to an anonymous method (this.Bar = b;
) or a concrete method (this.Whatever
)?
I checked the properties of action
. I couldn't find any property on action
(like IsAbstract
) of a IsAnonymous
kind. The underlying type is MethodInfo
which makes sense because after compiling I can see in ildasm the anonymous method "became" a normal method on Foobar
. In ildasm I can also see that the anonymous method is not a full pink square but a white square surrounded by pink and in its definition there's a call to some CompilerServices classes but I don't know how to take advantage of this back in C#. I'm sure it's possible to get to know about the real nature of action
. What am I missing?
For the sake of having an "accepted" answer on this question, I went as per the link given by Michael Kjörling in his first comment on my question.
if (action.Target.GetType().GetMethods().Where(method => method.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Any()).Contains(action.Method))
{
// ...
}
Compiler generated methods will always have their names with angled brackets like below
Void <Main>b__0()
so why not just fetch the name and see if it has angled brackets in it.
Action someaction = () => Console.Write("test");
string methodName= RuntimeReflectionExtensions.GetMethodInfo(someaction).ToString();
if(methodName.Contains("<"))
Console.write("anonymous");
or you can use much better pattern matching with regex
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With