How can I return “none” as a default case from a f

2019-09-03 08:54发布

问题:

I have this code (the whole story behind it is here: https://codereview.stackexchange.com/questions/28990/fancy-pants-vs-cowboy-coding):

public class BeltPrinterFactory : IBeltPrinterFactory
{
    public IBeltPrinter NewBeltPrinter()
    {
        switch (printerChoice)
        {
            case BeltPrinterType.ZebraQL220: 
                return new ZebraQL220Printer();
            case BeltPrinterType.ONiel: 
                return new ONielPrinter();
            default: 
                return new ZebraQL220Printer();
        }
    }
}

...but have added a "None" to the enum, as many customers will not have/use one:

public enum BeltPrinterType
{
    None,
    ZebraQL220,
    ONiel
    // add more as needed
}

The compiler won't allow me to not have a default case ("not all code paths return a value").

The "None" option perhaps should be the default case, but if None is the current value of printerChoice, the factory should never be called (the GUI that starts that ball rolling won't even be displayed when "None" is the value), but for the compiler's sake, how should this be implemented? Can I return nothing somehow? Or will I need to do something "weird" like:

    . . .
    default: 
        return new None();
    . . .

public class None : IBeltPrinter
{
    public void PrintLabel(string price, string description, string barcode)
    {
        ;// do nothing
    }
}

回答1:

If None isn't allowed option for factory, throw an exception.
If None is valid for factory, return dummy implementation of IBeltPrinter.
Do not return null.



回答2:

Throw a NotSupportedException at the end of such methods, do not return null.



回答3:

I'm going to take a stab at this.

Could this work for you?

public class BeltPrinterFactory : IBeltPrinterFactory
{
  public IBeltPrinter NewBeltPrinter()
  {
    BeltPrinter item = new BeltPrinter();
    switch (printerChoice)
    {
      case BeltPrinterType.ZebraQL220: 
        item.FunctionCall = ZebraCallback;
      case BeltPrinterType.ONiel: 
        item.FunctionCall = ONielCallback;
      default: 
        // do nothing;
    }
    return item;
  }
}

You'd need to create callbacks and redesign your IBeltPrinter, but Mayor Bloomberg and O.J. Simpson should be able to understand it.

Either that, or I don't really understand what you're asking.