Home > Blockchain >  Can a Method have Different Entry Points based on Argument
Can a Method have Different Entry Points based on Argument

Time:10-08

I have a method, but the whole method doesn't need to run all the time. I want only parts of the method to run sometimes.
In trying to follow DRY (Don't Repeat Yourself) principle, how can I have different entry points for this method based on a passed argument?

public void SetDisplayCollection(string input)
{
    //SWITCH:
    //Input 1 entry Point
    ChosenSite = SiteCollection.Where(x => x.Guid == chosenConcept.SiteGuid && x.Name == chosenConcept.SiteName).FirstOrDefault();
    //Input 2 entry point
    BuildingDisplayCollection = new ObservableCollection<BuildingConcept>(BuildingCollection.Where(x => x.RelatingName == ChosenSite.Name).ToList());
    ChosenBuilding = BuildingDisplayCollection.Where(x => x.Guid == chosenConcept.BuildingGuid && x.Name == chosenConcept.BuildingName).FirstOrDefault();
    //Input 3 entry point
    BuildingStoreyDisplayCollection = new ObservableCollection<BuildingStoreyConcept>(BuildingStoreyCollection.Where(x => x.RelatingName == ChosenBuilding.Name).ToList());
    ChosenBuildingStorey = BuildingStoreyDisplayCollection.Where(x => x.Name == chosenConcept.BuildingStoreyName).FirstOrDefault();
    //default no entry
}

For clarity sake, there are 3 desired scenarios:

  1. Run 100% of the code
  2. Run last 2/3 of the code (skip beginning)
  3. Run the last 1/3 of the code (skip 2/3)

CodePudding user response:

The simplest way would be to use if statements:

public void SetDisplayCollection(string input)
{
    if(input=="1")
    {
        ChosenSite = SiteCollection.Where(x => x.Guid == chosenConcept.SiteGuid && x.Name == chosenConcept.SiteName).FirstOrDefault();
    }
    if(input=="1" || input=="2")
    {
        BuildingDisplayCollection = new ObservableCollection<BuildingConcept>(BuildingCollection.Where(x => x.RelatingName == ChosenSite.Name).ToList());
        ChosenBuilding = BuildingDisplayCollection.Where(x => x.Guid == chosenConcept.BuildingGuid && x.Name == chosenConcept.BuildingName).FirstOrDefault();
    }
    if(input=="1" || input=="2" || input=="3")
    {
        BuildingStoreyDisplayCollection = new ObservableCollection<BuildingStoreyConcept>(BuildingStoreyCollection.Where(x => x.RelatingName == ChosenBuilding.Name).ToList());
        ChosenBuildingStorey = BuildingStoreyDisplayCollection.Where(x => x.Name == chosenConcept.BuildingStoreyName).FirstOrDefault();
    }
    //default no entry
}

Certainly you can rearrange the blocks to simplify the "if" logic, or separate the three blocks into separate functions and call them individually, or use more complicated patterns, but the first step is to get something that works, then make it better as time allows.

CodePudding user response:

Work backwards, and try to execute the last step first, unless the requirements aren't met (ChosenBuilding isn't defined yet). In that case, execute the second step first. Again, if the requirements of the second step (ChosenSite are not defined) then you need to run the first step.

This is called lazy evaluation, but the general idea is as follows:

public void SetDisplayCollection()
{
    if (ChosenBuilding == null)
    {
        if (ChosenSite == null)
        {
            // step #1
            ChosenSite = SiteCollection.Where(x => x.Guid == chosenConcept.SiteGuid && x.Name == chosenConcept.SiteName).FirstOrDefault();
        }
        // step #2
        BuildingDisplayCollection = new ObservableCollection<BuildingConcept>(BuildingCollection.Where(x => x.RelatingName == ChosenSite.Name).ToList());
        ChosenBuilding = BuildingDisplayCollection.Where(x => x.Guid == chosenConcept.BuildingGuid && x.Name == chosenConcept.BuildingName).FirstOrDefault();
    }
    // step #3
    BuildingStoreyDisplayCollection = new ObservableCollection<BuildingStoreyConcept>(BuildingStoreyCollection.Where(x => x.RelatingName == ChosenBuilding.Name).ToList());
    ChosenBuildingStorey = BuildingStoreyDisplayCollection.Where(x => x.Name == chosenConcept.BuildingStoreyName).FirstOrDefault();

}

Now can force the evaluation of steps #1 and steps #2 given an input.

Something like this

public void SetDisplayCollection(string input)
{
    if (ChosenBuilding == null || input == "1" || input == "2")
    {
        if (ChosenSite == null || input == "1")
        {
            // step #1
            ChosenSite = SiteCollection.Where(x => x.Guid == chosenConcept.SiteGuid && x.Name == chosenConcept.SiteName).FirstOrDefault();
        }
        // step #2
        BuildingDisplayCollection = new ObservableCollection<BuildingConcept>(BuildingCollection.Where(x => x.RelatingName == ChosenSite.Name).ToList());
        ChosenBuilding = BuildingDisplayCollection.Where(x => x.Guid == chosenConcept.BuildingGuid && x.Name == chosenConcept.BuildingName).FirstOrDefault();
    }
    // step #3
    BuildingStoreyDisplayCollection = new ObservableCollection<BuildingStoreyConcept>(BuildingStoreyCollection.Where(x => x.RelatingName == ChosenBuilding.Name).ToList());
    ChosenBuildingStorey = BuildingStoreyDisplayCollection.Where(x => x.Name == chosenConcept.BuildingStoreyName).FirstOrDefault();
}

CodePudding user response:

Don't add unnecessary load to your CPU. Building on D Stanley's answer, if you make your code slightly less DRY, you can significantly reduce the number of conditions that need processing:

if(new string[] { "1", "2", "3" }.contains(input))
{
    Function1();
    Function2();
    Function3();
}
else if(new string[] { "1", "2" }.contains(input))
{
    Function1();
    Function2();
}
else if(input=="1")
{
    Function1();
}

void Function1() {
    ChosenSite = SiteCollection.Where(x => x.Guid == chosenConcept.SiteGuid && x.Name == chosenConcept.SiteName).FirstOrDefault();
}

void Function2() {
    BuildingDisplayCollection = new ObservableCollection<BuildingConcept>(BuildingCollection.Where(x => x.RelatingName == ChosenSite.Name).ToList());
    ChosenBuilding = BuildingDisplayCollection.Where(x => x.Guid == chosenConcept.BuildingGuid && x.Name == chosenConcept.BuildingName).FirstOrDefault();
}

void Function3() {
    BuildingStoreyDisplayCollection = new ObservableCollection<BuildingStoreyConcept>(BuildingStoreyCollection.Where(x => x.RelatingName == ChosenBuilding.Name).ToList());
    ChosenBuildingStorey = BuildingStoreyDisplayCollection.Where(x => x.Name == chosenConcept.BuildingStoreyName).FirstOrDefault();
}

There's likely a nicer way to actually do what you're trying to do, but this is probably the most performant and least repetitive solution for your program as it stands.

  • Related