0

I know that this question has been asked a million times but all seem to refer to missing object or library references. I am declaring the variable "K" with a type of "TYPE". For some reason this will not build.

        foreach (var propertyInfo in typeof(T).GetProperties())
        {
            //
            // Gets the property from the obj
            MemberExpression propertyExpression = Expression.Property(Expression.Constant(obj), propertyInfo);
            //
            // get the data type of the property
            Type K = propertyExpression.Member.ReflectedType.UnderlyingSystemType;
            //
            // get the value of the property -- this line throws the error
            var currentValue = Expression.Lambda<Func<K>>(propertyExpression).Compile().Invoke();
        }

If I comment out the last line of the routine it compiles.

        foreach (var propertyInfo in typeof(T).GetProperties())
        {
            //
            // Gets the property from the obj
            MemberExpression propertyExpression = Expression.Property(Expression.Constant(obj), propertyInfo);
            //
            // get the data type of the property
            Type K = propertyExpression.Member.ReflectedType.UnderlyingSystemType;
            //
            // get the value of the property
            //var currentValue = Expression.Lambda<Func<K>>(propertyExpression).Compile().Invoke();
        }

When I comment out the last line I am able to build it. When I debug the code with the last line commented I get the same problem when I "watch" the variable as well. I had read that this could be because I was building in Release mode and it was discarding any variables it decide were unnecessary, however I am building in debug mode so ... ??

I feel like I have run into this problem several times over the years and have always "hacked" my way around it. I would like to understand what's happening so that I can resolve the problem rather than come up with some clever work-around.

Thank you

Gary O. Stenstrom
  • 2,284
  • 9
  • 38
  • 59
  • What is the *type* of `currentValue`? That's something that has to be determined by the compiler during compilation. But you're trying to involve an expression that will only be resolved at *runtime*. That's not going to work. References to runtime type *information* cannot be used in places where a type *itself* is expected to be used. – Damien_The_Unbeliever Oct 23 '17 at 14:44
  • Possible duplicate of [c# Creating an unknown generic type at runtime](https://stackoverflow.com/questions/8965893/c-sharp-creating-an-unknown-generic-type-at-runtime) – dymanoid Oct 23 '17 at 14:52
  • It doesn't know until runtime. It could be a string or it could be a custom class/object definition. Maybe what I am attempting can't be done, but why is **propType** being reported as not even existing? Even if I can't do this, would that explain why the **propType** declaration is failing? – Gary O. Stenstrom Oct 23 '17 at 15:00

2 Answers2

2
Expression.Lambda<Func<K>>(…)

That is creating an Expression<Func<K>> which needs K to be a type.

But you have a variable K.

But you appear to be creating expressions based on reflection to get the values of properties of a value. Just stick with reflection to do that:

// theObject is the input
foreach (var pi in theObject.GetType().GetProperties()) {
  object val = pi.GetValue(theObject);
  // do something with val
}
Richard
  • 106,783
  • 21
  • 203
  • 265
0

It's very likely related to the foreach context. Considering it's a dynamic context, meaning "K" will be a entirely new instance at each iteration, the Expression.Lambda statement may be rejecting the use of K (maybe it expects a constant like a class, not sure). Try using a for and numbered indexes instead and tell us the result.

Tiramonium
  • 557
  • 5
  • 15