I have a list that is derived from ProfileBase. This list can contains an instance of Profile,,DynamicViewProfile because both are derived from ProfileBase
But If the item type is DynamicViewProfile, i must use NodeName, if Profile then I should use DocName
profileListsForSearch = profileLists.Where(stringToCheck =>
((Profile)stringToCheck).DocName.Contains(searchBar.Text)).ToList();
So this is for profile and it is OK, but if the list contains DynamicViewProfile objects then i have an exception, because docname is null and i need to get NodeName
I hope my questions is clear
There's nothing special about LINQ here - you basically write the same code as you would normally, using is
or as
:
string searchText = searchBar.Text;
profileListsForSearch = profileLists
.Where(profile =>
profile is Profile
? ((Profile)profile).DocName.Contains(searchText)
: ((DynamicViewProfile)profile).NodeName.Contains(searchText))
.ToList();
That's assuming those are the only two types involved. If your list contains some other type, you'd get an InvalidCastException
.
However, this is pretty ugly - it feels like ProfileBase
should expose some property or method which indicates the general name - and then that could be implemented to return DocName
in Profile
and NodeName
in DynamicViewProfile
. Then you'd just need:
string searchText = searchBar.Text;
profileListsForSearch = profileLists
.Where(profile => profile.Name.Contains(searchText))
.ToList();
It's also future-proof in terms of adding new subclasses of ProfileBase
- and generally a cleaner use of polymorphism. Every time you need to cast - particularly conditionally casting to one thing or the other - consider whether a common method/property is feasible to make it cleaner.
See more on this question at Stackoverflow