5

I have a situation in C# web api function where I will need to retrieve a list of different objects from my database and need to implement some logic by invoking various methods.

How can I better achieve this by writing a Generic function for all 3 objects

example

there are two scenarios of locking list

  1. whole list is locked (do not proceed and throw exception if whole list is locked)

  2. only a single entity is locked (filter and remove this element if locked from the list)

    List<Object1> list1;
    List<Object2> list2;
    List<Object3> list3;
    
    private FilterLockedEntities(List<Object1> list1){
    
       if(list1[0].isListLocked) //whole list is locked
         throw ValidationException("Message")
    
       list1.RemoveAll(a => a.IsLocked); //filter locked entities
    
       //some more logic common to all
    
    }
    
    private FilterLockedEntities(List<Object2> list2){
    
       if(list2[0].isListLocked) //whole list is locked
         throw ValidationException("Message")
    
       list2.RemoveAll(a => a.IsLocked); //filter locked entities
    
       //some more logic common to all
    
    }
    
    private FilterLockedEntities(List<Object3> list3){
    
       if(list3[0].isListLocked) //whole list is locked
         throw ValidationException("Message")
    
       list3.RemoveAll(a => a.IsLocked); //filter locked entities
    
       //some more logic common to all
    
    }
    

I have the same logic in each of the three function but with List of different entities.

Is there a way where I can use a single method instead of three different functions its hard to maintain due to redundant logic. If there is a change in logic it needs to be updated in all the three places.

2
  • 3
    Can you change the definition of the objects? One easy way would be to just implement an interface with the "IsLocked" field. Commented Feb 8, 2016 at 23:48
  • Does the code in //some more logic common to all do anything with the lists? If so, what & how? If not, why is the code there? Commented Feb 9, 2016 at 0:24

3 Answers 3

2

Create a new interface:

public interface ILockable
{
    bool isListLocked();
}

Then make your object inherit the interface in their class declarations:

class Object1 : ILockable
{
    public IsLocked()
    {
        // Your code here...
    }
}
...
class Object2 : ILockable ...
class Object3 : ILockable ...

Then make your function accept a List of ILockable objects:

private FilterLockedEntities(List<ILockable> list)
{
    // Your code here...
}
Sign up to request clarification or add additional context in comments.

7 Comments

Since List<Object1> is not List<ILockable> this suggestion would be pain to implement as-is.
I was assuming Object1 thru Object3 were custom types and that the OP could modify the types by simply adding the interface inheritance, since the methods are already implemented on the object. If this is not the case, then yes, it would necessitate creating derived objects to implement.
You really should try to pass List<Object1> to your method and see what happens. Creating copy of List<Object1> just to call your method is not very good solution.
List objects are passed by reference in C#. My answer as proposed involves no copying of anything.
Casting List<Object1> to List<ILockable> creates a new list and the changes like remove from list to List<ILockable> doesn't reflect in the List<Object1>
|
1

You can also try dynamic

private FilterLockedEntities(dynamic list1){

   if(list1[0].isListLocked) //whole list is locked
     throw ValidationException("Message")

   list1.RemoveAll(a => a.IsLocked); //filter locked entities

   //some more logic common to all

}

A little unnecessarily broad for my tastes but perhaps fits your situation.

Comments

1

If you can add an interface IObject to Object1, Object2, and Object3, then more generics are the answer:

public interface IObject
{
    bool isLockedList { get; }
    bool IsLocked { get; }
}

private void FilterLockedEntities<T>(List<T> list) where T : IObject
{
    // same code as above should work here...
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.