Search code examples
c#.netdelegatesobjectlistview

How can this repetitive code be simplified?


The following code is very repetitive, but contains very slight differences in what properties are accessed. They change between RMs/FMs/FEs and PrimaryRM/PrimaryFM/PrimaryFE depending on which column the GroupKeyGetter applies to.

I can't find a way of converting this into a method so that I do not need to have this massive block of code, but there has to be a way of doing this in a better way...

allRMsColumn.GroupKeyGetter = delegate(object rowObject)
{
    var users = ((Tenant) rowObject).RMs.Trim().Split(new[] {", "}, StringSplitOptions.RemoveEmptyEntries);

    return users.FirstOrDefault(user => GlobalSettings.Users.Find(x => x.Name == user && x.Selected) != null) ?? ((Tenant)rowObject).PrimaryRM;
};

allFMsColumn.GroupKeyGetter = delegate (object rowObject)
{
    var users = ((Tenant)rowObject).FMs.Trim().Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries);

    return users.FirstOrDefault(user => GlobalSettings.Users.Find(x => x.Name == user && x.Selected) != null) ?? ((Tenant)rowObject).PrimaryFM;
};

allFEsColumn.GroupKeyGetter = delegate (object rowObject)
{
    var users = ((Tenant)rowObject).FEs.Trim().Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries);

    return users.FirstOrDefault(user => GlobalSettings.Users.Find(x => x.Name == user && x.Selected) != null) ?? ((Tenant) rowObject).PrimaryFE;
};

Any ideas at all?


Solution

  • You can make helper methods for extracting selected User, like this:

    private string GetFirstSelectedUser(string userList) {
        var users = userList.Trim().Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries);
        return users.FirstOrDefault(user => GlobalSettings.Users.Find(x => x.Name == user && x.Selected) != null);
    }
    

    Now all three delegates could be coded like this:

    allRMsColumn.GroupKeyGetter = delegate(object rowObject) {
        var renant = (Tenant) rowObject;
        return GetFirstSelectedUser(tenant.RMs) ?? tenant.PrimaryRM;
    };
    

    If you are free to make restructuring to the Tenant and can group FEs with PrimaryFE, FMs with PrimaryFM, and RMs with PrimaryRM, you could simplify your method even further:

    class GroupWithPrimary {
        public string Group {get;}
        public string Primary {get;}
        public GroupWithPrimary(string group, string primary) {
            Group = group;
            Primary = primary;
        }
    }
    private string GetFirstSelectedUser(GroupWithPrimary gp) {
        var users = gp.Group.Trim().Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries);
        return users.FirstOrDefault(user => GlobalSettings.Users.Find(x => x.Name == user && x.Selected) != null) ?? gp.Primary
    }
    allRMsColumn.GroupKeyGetter = delegate(object rowObject) {
        return GetFirstSelectedUser(((Tenant)rowObject).RM);
    };
    allFMsColumn.GroupKeyGetter = delegate(object rowObject) {
        return GetFirstSelectedUser(((Tenant)rowObject).FM);
    };
    allFEsColumn.GroupKeyGetter = delegate(object rowObject) {
        return GetFirstSelectedUser(((Tenant)rowObject).FE);
    };