Home > Enterprise >  Find all subclasses matching a List<string> property to another List (C#)
Find all subclasses matching a List<string> property to another List (C#)

Time:07-23

I'm trying to find all subclasses of an abstract class that have a matching entry in a List<string> property matching to another List<string>.

There are sufficient examples on Stack Overflow for standard properties (string, int, etc.), but the list seems to trip me over.

Here is my example:

public abstract class BaseClass
{
    internal abstract List<string> Employees();
}

public class ChildClass : BaseClass
{
    internal override List<string> Employees()
    {
        return new List<string>() 
        { 
            "John",
            "Mary",
        };
    }   
}

Now I want to find all subclasses inherting from BaseClass that have an Employee name in a predefined string. Something like this:

List<string> lookupList = new List<string>() { "Mary", "Peter" };
var allSubClasses = typeof(BaseClass)
                    Assembly.GetTypes()
                    .Where(t => t.IsSubclassOf(typeof(BaseClass)) && !t.IsAbstract)
                    .Select(t => (BaseClass)Activator.CreateInstance(t));
var matchingSubClasses = (from q in allSubClasses
                          where (q as BaseClass).Employees().Any(lookupList)  //Compile error on this line
                          select (q as BaseClass)).ToList();

This should return my ChildClass as the Employee name "Mary" appears in the lookup list.

I get a compiler error on the indicated line:

cannot convert from 'System.Collections.Generic.List' to 'System.Func<string, bool>'

Although the error makes sense, I can't seem to find a way to fix it :(

CodePudding user response:

To check if any of lookupList occurs in the Employees list of an object, you can use

Employees().Intersect(lookupList).Any()

Explanation: this determines the intersection of the two lists (i.e. the elements that occur in both) and the checks if this intersection contains any elements.

So this will work for your case:

var matchingSubClasses = (from q in allSubClasses
                          where q.Employees().Intersect(lookupList).Any()
                          select (q as BaseClass)).ToList();
  • Related