Search code examples
c#linqlinq-to-excel

Initialize an object before an if statement


in my program I am reading in an excel sheet and am doing some linq selections, which worked fine.

Problem: I tried to make a preselection by applying an If-statement. The variable will be assigned in every case (if/else) but the compiler doesn't see that. The compiler tells me to initialize the var beforehands but when I try that, I fail since I am only used to variables like sting, int or double which I can assign beforehands easily:

//This function takes the downloaded xlsx and makes selection of applicable items

var excel = new ExcelQueryFactory("list.xlsx");
//get all items with discount
if (onlyAcceptDiscountedItems == true)
{
    var discounts = from s in excel.Worksheet()
                    where s["Discount/Premium"].Cast<string>().StartsWith("-")
                    select s;
}
else
{
    var discounts = excel.Worksheet();
}
if (discounts.Count() != 0)
{
    //some application logic comes here
}

When I try To do it like that:

var excel = new ExcelQueryFactory("list.xlsx");ter code here
var discounts = excel.Worksheet();
if (onlyAcceptDiscountedItems == true)
{
    discounts = from s in excel.Worksheet()
                where s["Discount/Premium"].Cast<string>().StartsWith("-")
                select s;
}
if (discounts.Count() != 0)
{
    //some application logic comes here
}

I receive the following error at line 5 of the second codesnippet:

Error CS0266 Cannot implicitly convert type 'System.Linq.IQueryable' to 'LinqToExcel.Query.ExcelQueryable'. An explicit conversion exists (are you missing a cast?)


Solution

  • I see three options, although there are others:

    You could explicitly declare the type of variable you want, in which case you can initialize it separately in each case:

    IQueryable<LinqToExcel.Row> discounts;
    if (onlyAcceptDiscountedItems == true)
    {
        discounts = from s in excel.Worksheet()
                    where s["Discount/Premium"].Cast<string>().StartsWith("-")
                    select s;
    }
    else
    {
        discounts = excel.Worksheet();
    }
    

    You could use a conditional operator to initialize the variable:

    var discounts = onlyAcceptDiscountedItems
        ? excel.Worksheet().Where(s => s["Discount/Premium"].Cast<string>().StartsWith("-"))
        : excel.Worksheet();
    

    You could remove the redundancy of calling excel.Worksheet in two places:

    IQueryable<LinqToExcel.Row> discounts = excel.Worksheet();
    if (onlyAcceptDiscountedItems)
    {
        discounts = discounts.Where(s => s["Discount/Premium"].Cast<string>().StartsWith("-"));
    }
    

    Additionally, you may want to use discounts.Any() instead of discounts.Count() > 0, given that you don't really care about the count.