Reputation: 13965
I am building a method that takes a List<T>
and turns it into a DataTabe
. In the process, I want to filter out any properties that are tagged with the [NotMapped]
attribute.
I have the entire method working, but I am a bit worried about one part of it... the part that weeds out the [NotMapped]
properties. Here's what I've got:
public static DataTable CreateDataTable<T>(IEnumerable<T> list)
{
Type type = typeof(T);
var properties = type.GetProperties().Where(p =>
p.CustomAttributes.ToList().Count == 0 ||
(p.CustomAttributes.ToList().Count > 0 && p.CustomAttributes.ToList()[0].AttributeType.Name != "NotMappedAttribute")
).ToList();
// Rest of the method...
}
So, that works as I'd like it to and gets rid of anything that looks like this (for example) so it doesn't end up in the final DataTable
:
[NotMapped]
public string Description { get; set; }
My concern is about performance and just general best practice. The var properties =
LINQ query seems clumsy to me, but I'm not seeing a more efficient way to improve it.
Namely, I don't like calling p.CustomAttributes.ToList()
3 times. Is there a way to avoid this?
Upvotes: 0
Views: 125
Reputation:
To answer the original question, you can avoid calling ToList()
multiple times by saving its return value:
type.GetProperties().Where(p =>
p.CustomAttributes.ToList().Count == 0 ||
(p.CustomAttributes.ToList().Count > 0 && p.CustomAttributes.ToList()[0].AttributeType.Name != "NotMappedAttribute")
)
... becomes...
type.GetProperties().Where(p =>
{
var attrs = p.CustomAttributes.List();
return attrs.Count == 0 || (attrs.Count > 0 && attrs[0].AttributeType.Name != "NotMappedAttribute");
})
However, I recommend instead doing this:
type.GetProperties().Where(p => p.GetCustomAttribute<NotMappedAttribute>() == null))
Its shorter and easier to understand at a glance.
Upvotes: 0
Reputation: 29312
private IEnumerable<PropertyInfo> GetPropertiesWithoutAttribute<TAttribute>(Type type)
where TAttribute : Attribute
{
return type.GetProperties().Where(p => !p.GetCustomAttributes<TAttribute>().Any());
}
Upvotes: 3