0

I'm constructing a set of filter-classes which will all have the same method 'Applyfilter'.

How should I define the interface which contains apply filter? The only issue is that apply filter can take a second argument of various types e.g. int, string, Lists. Some pseudo code.

Current Interface method:

Data ApplyFilter(input-data, object value);

Example:

public *data* ApplyFilter(input-data, ***string color***) {
      // Do something with to data with the color string 
}

public *data* ApplyFilter(input-data, ***List<int> size***) {
      // Do something with to data with the size list
}

If I defined the type of argument two as an 'object'. I can do some validation within the ApplyFilter function. As mentioned here: Check if Object is Dictionary or List but is there a better way to do this?

2 Answers2

1

For centralized code , you can create a filter properties class

public class FilterProperties
{
    public string Color { get; set; }
    public List<int> Sizes { get; set; }
    //add filter properties as you want
}

Then create an ApplyFilter method that takes this class as an argument

public object ApplyFilter(List<object> inputData , FilterProperties filterProperties)
{
    var queryable = inputData as IQueryable<object>;

    // if the color property has value , then filter with it ,else don't filter
    if (!string.IsNullOrEmpty(filterProperties.Color))
    {
        queryable = queryable.Where(//your condition
                                   );
    }

    if (filterProperties.Sizes.Count > 0)
    {
        queryable = queryable.Where(//your condition
                                   );
    }
}

Now you have one filter method to avoid duplicating code, and have the flexibility to add new optional filters easily.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
kaarimtareek
  • 451
  • 3
  • 10
  • This might be the best approach... not type checking, It's similar to this answer. https://stackoverflow.com/questions/31781696/define-interface-method-with-different-parameters-in-c-sharp. The issue I have with it is the object will then always have all these properties. If there's 30 possible filters and only 4 are being used. Do i really want to construct an object with 30 poperties? – Simoplicity Mar 31 '22 at 06:05
  • 1
    @Simoplicity but you dont have to assign all 30 properties , you assign only the 4 you will use ,and it's centralized function , you don't have to copy/paste logic between all functions – kaarimtareek Mar 31 '22 at 14:11
0

An approach would be to use Generic

For exemple:

public interface Filter
{
    string ApplyFilter<T>(string inputData, T secondArgument);
}
public class MyImplementationClass : Filter
{

    public string ApplyFilter<T>(string inputData, T secondArgument)
    {
        throw new NotImplementedException();
    }
}
public class UseCase
{
    MyImplementationClass myImplementationClass = new MyImplementationClass();
    void applyFilter()
    {
        string color="";
        myImplementationClass.ApplyFilter<string>("input-data", color);
        List<int> size=new List<int>();
        myImplementationClass.ApplyFilter<List<int>>("input-data", size);
    }
}
Cyril ANDRE
  • 124
  • 9
  • Hi Cyril, this will be kicking the can down the road? I will still need to check the Generic T is a list of integers. – Simoplicity Mar 31 '22 at 06:04