I have looked at potentially duplicate questions, and this problem is not answered in any of them including Accessing Properties Through Generic Type Parameters
TLDR; typeof(T).GetProperty(propertyName)
does not work within a generic class when propertyName
of T is not declared public. Is there a workaround for this?
I have implemented an extension method that produces an IOrderedQueryable from a supplied string that contains the desired columns for sorting in an Entity Framework environment. The goal was to allow Order By clauses to be written in string form such as "+Age,+State,-Name" and produce the necessary expression to sort Entity Framework results by Age, State, and Name (descending), instead of having to write:
.OrderBy(m=>m.Age).ThenBy(m=>m.State).ThenByDescending(m=>m.Name)
.
The problem comes in when I try to access a class property that is marked internal. I cannot seem to find any way to force reflection to find that internal property.
In this particular case I have a datetime field in the database which is stored UTC but I want the end user to work with it in local time, so the value startTime, an internally scoped property is bound to the database and StartTime serves as a public accessor and provides access to the startTime value performing the necessary mapping to local time. I have a class defined as follows:
public class TimeInterval {
//other properties...
internal startTime { get; set; } // bound to database, stores time in UTC
public StartTime {
get { /*convert startTime to local time*/; }
set { /*convert value back to UTC and store in startTime*/; }
}
}
With EF I can write .OrderBy( m=>m.startTime )
and it works as expected; of course I cannot use .OrderBy( m=>m.StartTime )
because it is derived.
Within my extension function whose signature is
static public IOrderedQueryable<T> ParseOrderBy<T>(
this IQueryable<T> query,
string orderBy
)
which I would call using :
var query = query.ParseOrderBy<TimeInterval>( "startTime" );
my call to obtain the property reference to build a lamba expression returns null.
var property = typeof( T ).GetProperty( "startTime" );
property
comes back null for anything that is not explicitly public.
The extension method is in the same namespace and assembly as the classes I expect it to operate.