Switch chassis recording

Can anyone suggest me if there is a better way to write the below code using Swich case or whatever (thanks everyone for offering your valuable suggestions here, I am using it in a Linq query and I noticed some changes it contains different product names)

    from p in l_list
    where ((LicenceType == "Full" && SystemType == "Single") && p.ProductName != "Full DoubleProduct ")
       || ((LicenceType == "Full" && SystemType == "Multiple") && p.ProductName != "Full SingleProduct")
       || ((LicenceType == "Partial" && SystemType == "Single") && p.ProductName != "Locked DoubleProduct") 
       || ((LicenceType == "Partial" && SystemSize == "Multiple") && p.ProductName != "Locked SingleProduct")
       || ((LicenceType == "Locked" && SystemSize == "Single") && p.ProductName != "Locked DoubleProduct") 
       || ((LicenceType == "Locked" && SystemType == "Multiple") && p.ProductName != "Locked SingleProduct")

      

+3


source to share


5 answers


This monstrous boolean condition describes some common quality shared between a subset of your data objects. Identify this quality and give it a descriptive name.

Then, either output the value of that value through a property to your data object, or write an extension method that does the same. Finally, replace the existing condition to use this accessor.

For example, if the quality name is "friendliness", you can do this:



where model.IsFriendly // property

      

or that:

where model.IsFriendly() // extension method BusinessRules.IsFriendly(Model m)

      

+6


source


It looks like you can simplify your expression by "revoking" the license type and noticing that the condition boils down to a much simpler one

(
(SystemType == "Single"   && p.ProductName != "DoubleProduct") ||
(SystemType == "Multiple" && p.ProductName != "SingleProduct")
) &&
(
LicenceType == "Full"  ||
LicenceType == "Partial" ||
LicenceType == "NotApplicable"
)

      

If there are no license types other than "Full"

, "Partial"

and "NotApplicable"

, you can drop the second sentence for the final condition

(SystemType == "Single"   && p.ProductName != "DoubleProduct") ||
(SystemType == "Multiple" && p.ProductName != "SingleProduct")

      

EDIT: In general, when you have complex multipart conditions, your best bet is to extract the general subexpressions and try to reduce the number of conditions. The main problem is that you are trying to express in code that is a "linear" condition that has multiple dimensions; this "folding" makes the code difficult to read.



One way to solve this problem is to "encode" your condition in a table, for example:

var conditions = new[] {
    new[] { "Full",          "Single",   "Full DoubleProduct"    }
,   new[] { "Full",          "Multiple", "Full SingleProduct"    }
,   new[] { "Partial",       "Single",   "Locked DoubleProduct"  }
,   new[] { "Partial",       "Multiple", "Locked SingleProduct"  }
,   new[] { "NotApplicable", "Single",    "Locked DoubleProduct" }
,   new[] { "NotApplicable", "Multiple", "Locked SingleProduct"  }
};

      

Now you can use it like this:

Where (p => conditions.Any(cond =>
    cond[0] == p.LicenceType
 && cond[1] == p.SystemType
 && cond[2] != p.ProductName
))

      

The advantage of this approach is that the conditions are "tabulated" for the reader of your program and can be easily extended by simply adding new lines. The downside is that you can no longer run such a query against the origin IQueryable

without bringing the partial results into memory.

+4


source


You can use flags to indicate what value an object or attribute has.

[Flags]
enum MyEnum
{
    val1 = 0x01,
    val2 = 0x02,
    val3 = 0x04
}

      

You can use bitwise operators (& &, ||) to test a value. See here .

0


source


You can "encode" conditions as an array (matrix of states) and then use foreach / for and flags.

Another possible solution has bash.d

already been given - the use of bit fields. You can still combine both if you really need to.

I myself would avoid using duplicate strings (eg "Full"), instead putting them in constants to avoid errors and better readability (sometimes).

Also you don't need to use parentheses if the operands have the same priority, for example, you (a == b && c == d) && e == f

don't need marriages.

Last but not least, you can try to invert the logic, which can simplify the conditions, for example (a || b || c) = !(!a && !b && !c)

. This can be especially useful if you are dealing with a known subset of possible conditions, then you can "optimize" it.

0


source


In Linq, you can call external functions. So why don't you infer the "business logic" from the query? That is, you can create a method

bool IsLincensedForXXX(Product p)

      

and use it in a LINQ expression:

from p in l_list where IsLincensedForXXX(p)

      

I think it is cleaner, easier to use and easier to reuse.

0


source







All Articles