Reputation: 392
I have two classes derived from the same base class
public class AugInfo
{
public string UserId { get; set; }
public string Email { get; set; }
public bool EmailConfirmed { get; set; }
public string PhoneNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Name { get { return FirstName + " " + LastName; } }
public string Company { get; set; }
public string City { get; set; }
public string State { get; set; }
public Boolean LockedOut { get; set; }
public string Country { get; set; }
public int ModelsCount { get; set; }
public DateTime CreateDate { get; set; }
public string LoginProvider { get; set; }
public AugInfo() { }
}
public class AdminUserInfo : AugInfo
public class GroupUserInfo : AugInfo
And two functions described bellow
protected List<AdminUserInfo> FilterUsers(List<AdminUserInfo> users,SearchViewModel<AdminUserInfo, EnumUserSort> search)
{
if (!string.IsNullOrEmpty(search.SearchString))
{
users = users.Where(d =>
d.Email.ToLower().Contains(search.SearchString.ToLower())
|| d.Name.ToString().Contains(search.SearchString) ||
d.Company.ToString().ToLower().Contains(search.SearchString.ToLower())).ToList();
}
return users;
}
protected List<GroupUserInfo> FilterUsers(List<GroupUserInfo> users,SearchViewModel<GroupUserInfo, EnumUserSort> search)
{
if (!string.IsNullOrEmpty(search.SearchString))
{
users = users.Where(d => d.Email.ToLower().Contains(search.SearchString.ToLower())
|| d.Name.ToString().Contains(search.SearchString) ||
d.Company.ToString().ToLower().Contains(search.SearchString.ToLower())).ToList();
}
return users;
}
In this functions I use only those properties which belong to AugInfo
.
I wander is there a way to combine them into one function using Polymorphism
or Generic types
. I couldn't do that.
I've tried to declare a function something like this
protected List<AugInfo> FilterUsers(List<AugInfo> users,SearchViewModel<AugInfo, EnumUserSort> search)
{
if (!string.IsNullOrEmpty(search.SearchString))
{
users = users.Where(d => d.Email.ToLower().Contains(search.SearchString.ToLower())
|| d.Name.ToString().Contains(search.SearchString) ||
d.Company.ToString().ToLower().Contains(search.SearchString.ToLower())).ToList();
}
return users;
}
But unfortunately I can't call that function
List<AdminUserInfo> users= FilterUsers(users, search);
I get conver error
Upvotes: 0
Views: 91
Reputation: 273610
Generics should be used here:
protected List<T> FilterUsers<T>(List<T> users, SearchViewModel<T, EnumUserSort> search) where T : AugInfo {
if (!string.IsNullOrEmpty(search.SearchString)) {
users = users.Where(d =>
d.Email.ToLower().Contains(search.SearchString.ToLower())
|| d.Name.ToString().Contains(search.SearchString) ||
d.Company.ToString().ToLower().Contains(search.SearchString.ToLower())).ToList();
}
return users;
}
Just writing List<AugInfo>
is not enough here because List<T>
is not contravariant and covariant at the same time (such thing does not exist in C#). You can't convert List<BaseType>
to List<DerivedType>
.
Upvotes: 2
Reputation: 37095
You need egeneric constraint on T
so that only types deriving from AugInfo
can be used as generic argument:
protected List<T> FilterUsers<T>(List<T> users, SearchViewModel<T, EnumUserSort> search) where T: AugInfo
{
if (!string.IsNullOrEmpty(search.SearchString))
{
users = users.Where(d =>
d.Email.ToLower().Contains(search.SearchString.ToLower())
|| d.Name.ToString().Contains(search.SearchString)
|| d.Company.ToString().ToLower().Contains(search.SearchString.ToLower())).ToList();
}
return users;
}
Upvotes: 2