Karen Avdalyan
Karen Avdalyan

Reputation: 392

Polymorphism not understanding

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

Answers (2)

Sweeper
Sweeper

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

MakePeaceGreatAgain
MakePeaceGreatAgain

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

Related Questions