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.