简体   繁体   中英

How to assign values of different types to a variable inside if statements and then use this variable after the if statements?

I am retrieving different types of documents from database, and assigning the received data to the variable items . Different methods are used to retrieve different document types, hence the need for if statements. I cannot initialize items before the if statements, because I don't know beforehand what type of document the user is retrieving. The problem is that I therefore cannot use items after the relevant īf statement has been executed. How to solve this issue? A simplified method:

public ActionResult ExportToExcel()
{
  ...
  if (request.docType == "docType1")
  {  
    var items = _provider.GetDocumentsOfType1(request);
  }
  else if (request.docType == "docType2")
  {
    var items = _provider.GetDocumentsOfType2(request);
  }
  else if ...

}

After retrieving the data, I would need to do some formatting based on what data is in the items variable, and of course return the data. It seems that the only viable thing is to replace the if statements with separate methods, and call the formatting etc. methods from there. But can it all be done within a single method?

You can use dynamic pseudo-type. Or, you can declare variable as object.

The both of these solutions have drawbacks.

The best solution would be using an interface, which is provided by every possible types of documents.

To avoid multiple if statements, you can use the SOLID design principle. So, you can do this:

interface IExcelDoc
{
 ActionResult ExportToExcel();
}

public class ExcelDoc1 : IExcelDoc
{
    public ActionResult ExportToExcel()
    {
       // implementation here
    }
}

public class ExcelDoc2 : IExcelDoc
{
    public ActionResult ExportToExcel()
    {
       // implementation here
    }
}

Then your driver class can be like:

public class Test 
{
    public void Main()
    {
       IExcelDoc excelDoc = GetDocType();
       excelDoc.ExportToExcel();
    }

    private IExcelDoc GetDocType()
    {
     if(...)
        return new ExcelDoc1();
     else
        return new ExcelDoc2();
    }
}

This will make your code maintainable in future.

See if you can use an interface that is shared between the various document types, or else create such an interface:

public interface IDocument { }

public class Doc1 : IDocument { }

public class Doc2 : IDocument { }

If the various DocX classes have shared properties or operations that you need to use, then by all means add those into the IDocument interface, that will make them callable without any need for type checking and type casting.

You can then declare items as IEnumerable<IDocument> , and have the GetDocumentsOfTypeX() -methods all return a value of that type:

IEnumerable<IDocument> items;

items = GetDocumentsOfType1();

public static IEnumerable<IDocument> GetDocumentsOfType1()
{
    return new List<Doc1>() { new Doc1() };
}

// (etc)

Working demo: https://dotnetfiddle.net/Dwmmdf

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM