Search code examples
c#delegation

Select one of two different methods in a method chain in C#


Consider the following code:

decimal userPrice = product.Status == ProductStatusEnum.Presale
   ? pricingHelper.GetUserPresalePricing(sku, user).UserCustomPrice
   : pricingHelper.GetUserProductPricing(sku, user).UserCustomPrice;

Is there some way to place the expression that determines which method to use inside the method chain instead of having to use two complete method chains? My mind goes to the use of a delegate or perhaps calling by name using reflection, but neither of those strike me as reasonable solutions (especially the calling by name).

I realize in this case that the method chain is not long (there's just one property afterward), but imagine a scenario with a much longer method chain. I like method chaining over creating a lot of variables, however, for clarity, in a long method chain having a difference in method usage like this, I'd choose temporary storage in a variable over repeating myself. But does it have to be that way?

In javascript this would be quite simple:

var userPrice = pricingHelper[
   product.Status === ProductStatusEnum.Presale
   ? GetUserPresalePricing
   : GetUserProductPricing
](sku, user).UserCustomPrice;

Also, perhaps placing one of the two methods into a variable and then using that variable, as in (bad pseudocode):

SomeDelegate = product.Status == ProductStatusEnum.Presale
   ? pricingHelper.GetUserPresalePricing
   : pricingHelper.GetUserProductPricing;

decimal userPrice = SomeDelegate(sku, user).UserCustomPrice;

Given that C# can do most things that functional languages can, there has to be a way (not saying it's necessarily better than the starting code above, just wondering).

Your comments on whether such a construction is useful or clearer than the original code are also welcome.

One more thought comes to mind, which is that in the pricingHelper class, I could create a GetUserPricing method that takes a parameter indicating whether to get the presale or product pricing. Hmmm...


Solution

  • var f = product.Status == ProductStatusEnum.Presale
       ? new Func<Sku, User, CustomPrice>(pricingHelper.GetUserPresalePricing)
       : pricingHelper.GetUserProductPricing;
    
    decimal userPrice = f(user, price).UserCustomPrice;