Reputation: 335
I currently have a function that gets the type of a property of an object and it can be seen below.
private static Type GetPropertyType<TClass, TResult>(Expression<Func<TClass, TResult>> propertyExpression)
{
Type type = propertyExpression.Body.Type;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = Nullable.GetUnderlyingType(type);
}
return type;
}
Now, the problem with this is that i need to have an instance of the object that i intend to get the type of the property as seen below
var baseZoneTypeEntity = zoneTypeCollection.First();
Type t = GetPropertyType(() => baseZoneTypeEntity.BonusAmount);
I would like to have something like you pass the class instead of passing an instance, so something
Type t = GetPropertyType<ZoneTypeClass>(_ => _.BonusAmount);
Expressions are quite new to me and im trying to convert this for half an hour already and to no avail.
Can you guys help me convert this to a class based from an object based one?
Thank you.
Upvotes: 0
Views: 137
Reputation: 875
you need to change the expression parameter to object try this.
private static Type GetPropertyType<TClass>(Expression<Func<TClass, object>> propertyExpression)
{
var unaryExpression = propertyExpression.Body as UnaryExpression;
if (unaryExpression == null) return propertyExpression.Body.Type;
var type = unaryExpression.Operand.Type;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof (Nullable<>))
{
type = Nullable.GetUnderlyingType(type);
}
return type;
}
UPDATED : the expression body needs to be casted to UnaryExpression the above should work Then you can use it as
var type= GetPropertyType<CustomerEntity>(x => x.FirstName);
Or
var type= GetPropertyType<ProductEntity>(_ => _.Price);
Upvotes: 0
Reputation: 27095
In your current approach you'd write:
Type t = GetPropertyType<ZoneTypeClass, int>(_ => _.BonusAmount)
Which is redundant since you'd either have to pass in an instance or specify the resulting type. You could rewrite the method to not care about the resulting type, but leave it as object
. This is possible because you are inspecting the expression body, allowing the desired behavior posted in your question (using _ => _.Property
).
static Type GetPropertyType<TObject>(Expression<Func<TObject, object>> propertyExpression)
{
var expression = propertyExpression.Body;
var unaryExpression = expression as UnaryExpression;
if (unaryExpression != null)
{
expression = unaryExpression.Operand;
}
Type type = expression.Type;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = Nullable.GetUnderlyingType(type);
}
return type;
}
Why the weird UnaryExpression
if
statement? If your property type is not of type object
, the expression will evaluate to _ => ((object)_.Property)
. The UnaryExpression
is the type conversion part, which we are eliminating there.
Upvotes: 1