0

I need a reliable way to distinguish compiler generated closure objects.

I found a viable solution using CompilerGeneratedAttribute: How to distingush compiler-generated classes from user classes in .NET It turns out i can use CompilerGeneratedAttribute.

Here is my current code:

static bool IsClosure(Type t)
{
    return IsCompilerGenerated(t) && !t.Name.Contains("AnonymousType");
}

static bool IsCompilerGenerated(Type t)
{
    return Attribute.IsDefined(t, typeof(CompilerGeneratedAttribute), false);
}

void Main()
{
    var site = new Model();

    var propertyExpression = (Expression<Func<string>>)(() => site.Prop);
    var memberAccess = (MemberExpression)propertyExpression.Body;
    var modelExpression = (MemberExpression)memberAccess.Expression;
    var closureExpression = (ConstantExpression)modelExpression.Expression;
    var closureType = closureExpression.Value.GetType();

    Console.WriteLine("Type: {0} Is closure: {1}", closureType, IsClosure(closureType));

    var anonymous = new { x = 0 };

    Console.WriteLine("Type: {0} Is closure: {1}", anonymous.GetType(), IsClosure(anonymous.GetType()));
}

class Model
{
    public string Prop { get; set; }
}

Output:

Type: MyClass+<>c__DisplayClass0_0 Is closure: True
Type: <>f__AnonymousType0`1[System.Int32] Is closure: False

As i understand from and Anonymous Types - Are there any distingushing characteristics? about anonymous objects, is that the problem is similar for compiler generated closure types, and distinguishing characteristics are essentially an implementation detail. Is that the case?

Is there a more reliable method to distinguish closure objects, considering portability to mono and future versions of .NET?

Community
  • 1
  • 1
George Polevoy
  • 7,450
  • 3
  • 36
  • 61
  • 1
    It's almost always wrong to put yourself in a position where you'd *care* if a type is a closure type or not. – Servy Oct 14 '15 at 14:21
  • @Servy If you are interested why it's necessary - a big legacy framework which makes use of expressions in form () => Prop (used in an instance method of a model, and possibly () => site.Prop (used outside of the mode), which are then processed with an expression visitor to a form of (model) => Prop, that's why i need to dig inside the expression for a FieldExpression->ConstantExpression->Value which holds an example model in closure. – George Polevoy Oct 14 '15 at 14:38
  • 1
    Then you very clearly don't need to know this. You don't need to know if that type is a closure type. Just traverse the expression tree all the way to the top, rather than until you get to a closure type. Whether the body uses a closure, or some other means of accomplishing the goal, shouldn't matter to you in that context; you should be doing the same thing *regardless of whether a closure is used or not*. – Servy Oct 14 '15 at 14:42
  • The same Constant is generated for `this`, that's why i can't. And `this` is implied to be the model, which i then need to promote to a parameter with PrameterExpression. – George Polevoy Oct 14 '15 at 14:49
  • Which you can do just fine without needing to know or care if that top level object is compiler generated or not. – Servy Oct 14 '15 at 14:58
  • In case of `this`, the said Constant.Value holds the model itself (`this`), but in case of a closure, the model is a FieldExpression(ConstantExpression) and i need to extract that with fieldInfo.GetValue. – George Polevoy Oct 14 '15 at 15:02
  • 1
    Closing over `this` *creates a closure*, so you have a closure in both cases. So clearly you have some means of determining which expression represents the model beyond just whether or not the object is a closure object; use that. – Servy Oct 14 '15 at 15:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/92281/discussion-between-george-polevoy-and-servy). – George Polevoy Oct 14 '15 at 15:07

0 Answers0