user3685427
user3685427

Reputation: 219

Can a function return a static function?

TL;DR: the title says it all, and a simple answer would be great if the question can be answered simply

Longer Version: I am using a pre-existing library to build invoices, and the library holds the instantiation of the invoice object and static functions which add items to the invoice. The items on the invoice include breakdowns of sub-items, and it has about a dozen columns. No item uses all the columns, and the column usage and values depends on the item listed and it's depth within a breakdown.

So, the invoice can be built with pseudocode like this:

Invoice customerInvoice = new Invoice();
MainItem widget = new MainItem(); //the entirety of the sale, this is shown as the top-level item
SubItem component = new SubItem(widget, values[]); //a component of widget. The parameters identify the main piece that this attaches to, and a set of values for the other columns.
SubItem piece = new SubItem(widget, values[]); //another component; the values[] will be slightly different but correspond to the same columns.
SubItem bolt = new DeepSubItem(piece, lowestValues[]); //an irreducibly small item which is a part of the "piece" item, with it's own set of values which fill a different arrangement of columns

Components and sub-components are shown on indented lines below their parent object. I am trying to create a new class structure that can help simplify this. The largest problem is that values[] here represents about 20 individual parameters. Additionally, a maze of conditional statements is necessary due to quirks of individual products, variations based on sale location or time, and many other factors. The only constant is that each function corresponds to a single line on the invoice. The original library was great at nesting objects properly, but it can't handle the logic. The SubItem instantiations of piece, bolt, and component only exist so that they can be broken down. When SubItem() or DeepSubItem() are called, the objects are attached to the object that they include in their parameter.

First question: What is a good plan/design pattern/strategy to build a new structure that can use the existing library, but provide flexible logic?

Second question: If I could create an 'instance' of the static functions, I could use that instance without the great verbosity of the parameters. Is there any way to do this, or something that will have a similar effect?

I've been thinking of creating a new class that will conduct the logic and hold the needed sets of values. That class can then create 'objects' (ideally, instances of the static functions) which I can use in the code we already have, replacing the function calls. That would allow me to separate the verbosity (which rarely needs to change) from the logic (which often needs to change). I can't simply use the object "bolt" because the moment I instantiate it, it is added to the invoice - hence why I want to treat the function like an object.

Your wise input (and/or reality check) is greatly appreciated. Thanks,

Upvotes: 0

Views: 134

Answers (2)

furkle
furkle

Reputation: 5059

One of the ways you could do this would be to use the Func object. This allows you to pass functions by reference. Here's an example:

 private static object TestStaticFunction()
 {
    return "test";
 }

 public static Func<object> GetStaticFunction
 {
     get { return TestStaticFunction; }
 }

Then, any function that calls GetStaticFunction will get TestStaticFunction returned to it. Likewise, Console.Write(GetStaticFunction()) will display "test".

Note that if you want to pass a method that does not return a value, use Action instead.

Here's the MSDN documentation on Func: http://msdn.microsoft.com/en-us/library/bb549151%28v=vs.110%29.aspx

And another StackOverflow thread with more explanation: What is Func, how and when is it used

As far as your program design, I'm not really sure that I understand the library well enough to point you towards a better pattern. Are you forced to work within this library?

Upvotes: 1

matt-dot-net
matt-dot-net

Reputation: 4244

Are you talking about delegates?

class Program
{
    static void Main(string[] args)
    {
        var returnedFunction = TestClass.FunctionToReturnAStaticMethod();
        returnedFunction();
    }
}

public class TestClass
{
    public delegate void TypeOfFunctionToReturn();

    public static TypeOfFunctionToReturn FunctionToReturnAStaticMethod()
    {
        return () => StaticMethod();
    }

    public static void StaticMethod()
    {
        Console.WriteLine("\"StaticMethod\" called");
    }
}

Upvotes: 0

Related Questions