简体   繁体   中英

C# - Method with Generic Property

I've seen plenty of examples of how to use generic Objects in C#, but can I have a generic property for a static object?

I have 2 distinct lists of Providers:

List<Providers> OldProviders
List<Providers> NewProviders

OldProviders has providers from the database, and NewProviders has providers the user has selected in the View. If any OldProviders aren't in NewProviders, I want to remove them from the database. If any NewProviders aren't in OldProviders, I want to add them to the database. Simple.

One problem: Provider has 2 properties that correspond to foreign keys important for comparison: StaffID and LicenseID (both integers) Depending on the choice the user makes, I only care about one of these IDs.

Currently I have 2 sets of helper methods which are completely identical (6 total helpers), except for whether they compare using StaffID or LicenseID. It technically works, but I don't want to maintain it.

Here's an example:

private bool DeleteOldStaffProviders(List<Provider> oldSelectedStaff, List<Provider> newSelectedStaff)
        {
            foreach (var oldSelected in oldSelectedStaff)
            {
                bool remove = newSelectedStaff.SingleOrDefault(n => n.StaffID == oldSelected.StaffID) == null;
                if (remove)
                {
                    //<remove from database, return false if failure>
                }
            }
            return true;
        }

Is there a way I can rewrite this method with a generic parameter reference? ie

newSelectedStaff.SingleOrDefault(n => n.T == oldSelected.T) 

where T is either LicenseID or StaffID.

I've seen a lot of examples of people using LINQ and reflection for things kinda similar to this, but I can't seem to figure it out. If you could baby me through it, that would be appreciated.

Yes, use another parameter of type Func<Provider,int> to act as the selector:

private bool DeleteOldStaffProviders(List<Provider> oldSelectedStaff, List<Provider> newSelectedStaff, Func<Provider,Provider,bool> selector)
{
    foreach (var oldSelected in oldSelectedStaff)
    {
        bool remove = newSelectedStaff.SingleOrDefault(n => selector(n) == selector(oldSelected)) == null;
        if (remove)
        {
            //<remove from database, return false if failure>
        }
    }
    return true;
}

usage

DeleteOldStaffProviders(oldStaff, newStaff, x => x.StaffID);
DeleteOldStaffProviders(oldStaff, newStaff, x => x.LicenseID);

You could do it another way - but I think its more clunky. Pass in a Func<Provider,Provider,bool> like this:

DeleteOldStaffProviders(oldStaff, newStaff, (o,n) => o.StaffID == n.StaffID);

And change a line to:

bool remove = newSelectedStaff.SingleOrDefault(n => selector(n,oldSelected))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM