1

I have a use case where I would like to get the custom attributes off of a member in a LINQ Lambda Expression. However, I'm noticing that in cases where the member is overridden, LINQ is actually returning the member on the base class instead of the sub class, thus providing me with only the custom attributes on the base class. I've come up with a simple example to sort of demonstrate the issue I'm running into.

using System;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;

class MyAttribute : Attribute {
  public override string ToString() {
    return "Found it!";
  }
}

class BaseClass {
  public virtual int MyInt { get; set; }
}

class SubClass : BaseClass {
  [MyAttribute()]
  public override int MyInt
  { 
    get => base.MyInt; 
    set => base.MyInt = value;
  }
}

class MainClass {

  public static void Main (string[] args) {
    Expression<Func<BaseClass, int>> baseExpr = b => b.MyInt;
    Expression<Func<SubClass, int>> subExpr = s => s.MyInt;
    var subMember = typeof(SubClass).GetMember("MyInt").First();

    Console.WriteLine((baseExpr.Body as MemberExpression).Member.DeclaringType);
    Console.WriteLine((baseExpr.Body as MemberExpression).Member.GetCustomAttribute<MyAttribute>());
    // BaseClass
    // 

    Console.WriteLine((subExpr.Body as MemberExpression).Member.DeclaringType);
    Console.WriteLine((subExpr.Body as MemberExpression).Member.GetCustomAttribute<MyAttribute>());
    // BaseClass
    //

    Console.WriteLine(subMember.DeclaringType);
    Console.WriteLine(subMember.GetCustomAttribute<MyAttribute>());
    // SubClass
    // Found it!
  }
}

I had thought about simply looking at the expression component of the Member Expression to see what the actual type is, and use that to look up the correct member based on that, but it seems like it might fail on various edge cases, notably if the sub class has a different member with the same name than the base class. If I wanted to do something like this, I would probably need a way to search for members that override the member given to me by linq, though I'm not seeing any obvious way to do that search.

What would be the best way to get the correct attributes off of the member in the expression tree?

  • Does this answer your question? [How to get the child declaring type from an expression?](https://stackoverflow.com/questions/9466582/how-to-get-the-child-declaring-type-from-an-expression) – Guru Stron Jun 03 '20 at 21:45
  • @GuruStron I didn't see that before, thanks! I think the question is related, but I'm not actually seeing any fully working solutions in that post. It does explain why I'm having this issue though. – Harrison Lambeth Jun 03 '20 at 21:56
  • Can you please add the actual usecase? What information and when do you need? – Guru Stron Jun 03 '20 at 22:04
  • @GuruStron I updated the question slightly to hopefully clarify what I'm trying to do. In the question you linked the accepted answer actually only explains why c# returns the member from the base class, but provides no insight into how to get the attributes from the member. The other answers provide some hints, but seem to rely on nonexistant apis (maybe they are obsolete?), or they might fail on the edge case I listed in my question. Ideally I just need a way to find the member on the child class that overrides the base member provided by .net, but there may be a better solution. – Harrison Lambeth Jun 03 '20 at 22:24

0 Answers0