2

I have several methods in my DAL, with quite a few parameters:

public Collection<Proforma> SearchAllProforma(DateTime? startDate = null, DateTime? endDate = null,
        int? institutionID = null, int? inspectionID = null, bool? isFollowup = null, bool? excludeDeleted = null,
        bool? nutritionalOnly = null, int? parentInspectionID = null)

Should I condense these down to take an object parameter? Or leave them the way they are, using optional parameters? Or both?

Edit - I should really have said, that each one of these parameters maps to a parameter for a stored procedure.

ScottD
  • 173
  • 5
  • 15

7 Answers7

1

Should I condense these down to take an object parameter?

Not necessarily. The default values seem okay (I assume your function can handle null parameters without issue). If you're using a recent version of C# you can call this function like:

SearchAllProforma(institutionID: 33);

Which isn't all that bad, in my opinion.

ta.speot.is
  • 26,914
  • 8
  • 68
  • 96
1

I would suggest you to Create a class for all those parameter as properties.

And then send the class as parameter.

Class SerachAllProformaParameter
{
//All Properties.
}

SerachAllProformaParameter parameter= new SerachAllProformaParameter();
parameter.PropertyName="value";

public Collection<RoIVProforma> SearchAllProforma(parameter);
Kishore Kumar
  • 12,675
  • 27
  • 97
  • 154
  • I think that I am going to try this approach out, alongside my existing approach, and see which I prefer. I am not sure that I like the syntax for calling the methods though. Seems clunky (especially in VB.NET). – ScottD May 24 '12 at 10:55
  • And also, I have a lot of methods with many parameters, so implementing loads of classes for each of these might be a lot of work. – ScottD May 24 '12 at 11:48
0

Consider that a lot of them have their default values, for usability perspctive I would add several overrides of this method with different quantity of parameters.

In this way, for a consumer of your method would be easier to choose appropriate one without having in front of eyes all that parameters in intellisense window.

public Collection<RoIVProforma> SearchAllProforma(DateTime? startDate = null) 
{
   ...
}

public Collection<RoIVProforma> SearchAllProforma(DateTime? startDate = null, DateTime? endDate = null)
{
 ...
}

public Collection<RoIVProforma> SearchAllProforma(DateTime? startDate = null, DateTime? endDate = null,
        int? institutionID = null)
{
 ...
}

...
Tigran
  • 61,654
  • 8
  • 86
  • 123
  • I don't see the advantage in adding multiple overloads for a method that already has every parameter as optional. Just seems like extra noise and stuff that I have to maintain to me. – ScottD May 24 '12 at 09:39
  • @ScottD: as I wrote, the benefit is when you write "." in intellisense you see not all that parameters, but like a first option would see the method with no parameters, and after can use "<" and ">" to go for other definitions. – Tigran May 24 '12 at 09:46
0

Should I condense these down to take an object parameter?

Yes, absolutely. Looking at this method signature makes my eyes start bleeding.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
0

Personally, the best way here is to pass an Expression<Func<RoIVProforma, bool>> instance into SearchAllProforma method. But it is more hard to implement parsing expression, if your DAL doesn't use any LINQ-based underlying data source.
The same time, a method with many optional parameters is the worst.

Dennis
  • 37,026
  • 10
  • 82
  • 150
0

Use object as parameter, it is a good approach..

Talha
  • 18,898
  • 8
  • 49
  • 66
0

You can pass a predicate lambda expression to the method if all the arguments belong to some entity of yours.

I use following method to search for some criteria among my entities.

public List<Personel> GetAll(Func<Personel, bool> predicate = null)
        {
            List<Personel> result = new List<Personel>();

            if (predicate == null)
            {
                result = personelRepo.Table.ToList();
            }
            else
            {
                foreach (var item in personelRepo.Table)
                {
                    if (predicate(item))
                        result.Add(item);
                }
            }

            return result;
        }

and then pass a predicate to the method when calling like:

var myFilteredEntities = GetAll(e => e.Name == "John" && e.IsMarried == false);
Mert Akcakaya
  • 3,109
  • 2
  • 31
  • 42