I have this class:
public class user
{
public string FirstName { get; set; }
public string LastName { get; set; }
public EyeColor EyeColor { get; set; }
}
public enum EyeColor
{
Brown,
Black
}
I can use user.GetType().GetProperties();
to get properties and then get values of them.
But for enums is different, all I want to do is: getting Enum index, for example brown is 0
and black is 1
for dynamic search on enum fields.
But I have a generic method to get index and I can't use int enumIndex = (EyeColor)user.EyeColor;
because I don't know what kind of enum will be pass to the generic method.
public static IQueryable<T> CreateEqualExpressions<T>(IQueryable<T> query, object model)
{
var result = query;
var propertiesToSearch = model.GetType().GetProperties()
.Where(x => Attribute.IsDefined(x, typeof(EqualSearchAttribute)))
.ToList();
if (propertiesToSearch.Count > 0)
{
foreach (var propertyInfo in propertiesToSearch)
{
var propertyValue = propertyInfo.GetValue(model);
if (!string.IsNullOrWhiteSpace(propertyValue?.ToString()))
{
var parameter = Expression.Parameter(typeof(T));
var property = Expression.Property(parameter, propertyInfo.Name);
if (propertyValue is string)
propertyValue = propertyValue.ToString()?.Trim();
var constantValue = Expression.Constant(propertyValue);
var equal = Expression.Equal(property, constantValue);
var exp = Expression.Lambda<Func<T, bool>>(equal, parameter);
result = result.Where(exp);
}
}
}
return result;
}
Everything is ok for strings but for enums not works because propertyValue
is: Brown
or Black
, but for dynamic search, I need to index of them like 0
or 1
.
Any suggestion ?
CodePudding user response:
If I understand correctly, you just need Convert.ToInt64
to convert the enum value to a long
, which fits every enum underlying type.
var value = propertyInfo.GetValue(model);
if (propertyInfo.PropertyType.IsEnum) {
long underlyingEnumValue = Convert.ToInt64(value);
// construct your expression here...
}
Note that if you are constructing an Expression.Equal
, with one of the operands being the EyeColor
property access, you should convert that to long
too:
var equal = Expression.Equal(
Expression.Convert(property, typeof(long)),
Expression.Constant(underlyingEnumValue)
);
Example code:
var prop = typeof(User).GetProperty("EyeColor")!;
var value = prop.GetValue(new User() { EyeColor = EyeColor.Black });
var underlyingEnumValue = Convert.ToInt64(value);
var p = Expression.Parameter(typeof(User));
var lambda = Expression.Lambda(
Expression.Equal(
Expression.Convert(
Expression.Property(p, prop),
typeof(long)), Expression.Constant(underlyingEnumValue)
), p
);
var del = lambda.Compile();
var result1 = del.DynamicInvoke(new User() { EyeColor = EyeColor.Brown });
var result2 = del.DynamicInvoke(new User() { EyeColor = EyeColor.Black });
Console.WriteLine(result1); // False
Console.WriteLine(result2); // True
CodePudding user response:
What about something like this?
var type = propertyInfo.PropertyType;
if (type.IsEnum)
{
var enumIndex = (int) propertyValue;
}