Reputation: 303
Can anyone please suggest me, is there any better way in writing the below code using Swich case or any(Thank you all for giving your valuable suggestions here I am using it in Linq query and I observed some modifications that 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")
Upvotes: 3
Views: 240
Reputation: 4628
In Linq you can call external functions. So why don't you move the "business logic" out of the query? I.e. you can create a method
bool IsLincensedForXXX(Product p)
and use it in the LINQ expression:
from p in l_list where IsLincensedForXXX(p)
I think it is cleaner, easier to mantain and to reuse.
Upvotes: 0
Reputation: 726479
It looks like you can simplify your expression by "factoring out" the license type, and observing that the condition boils down to a much simpler
(
(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 throw away the second clause for the final condition of
(SystemType == "Single" && p.ProductName != "DoubleProduct") ||
(SystemType == "Multiple" && p.ProductName != "SingleProduct")
EDIT: In general, when you have complex multi-part conditions like that, the best you can do is extracting common sub-expressions, and trying to reduce the number of conditions. The fundamental issue is that you are trying to express in code which is "linear" a condition which has multiple dimensions; this "folding" results in code that is hard to read.
One way around this problem is "encoding" your condition in a table, like this:
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 in a condition 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 simply by adding new rows. The disadvantage is that you can no longer run a query like that against an IQueryable
source without bringing partial results into memory.
Upvotes: 4
Reputation: 21979
You can "code" conditions as array (state matrix), then use foreach/for and flags.
Another possible solution was given by bash.d
already - use bitfields. You can further combine both if you really have to.
I'd myself avoid using repetitive strings (like "Full"), rather put them in constants to avoid making mistakes and for better readibility (sometimes).
Also you don't need to use brackets when operands have same priority,to example, (a == b && c == d) && e == f
don't need brakets.
And last, but not least, you can try to invert logic, which may simplify conditions, to example, (a || b || c) = !(!a && !b && !c)
. This can be especially useful if you are dealing with known subset of possible conditions, then you can "optimize" it.
Upvotes: 0
Reputation: 13207
You could use flags to indicate what value an object or an attribute has.
[Flags]
enum MyEnum
{
val1 = 0x01,
val2 = 0x02,
val3 = 0x04
}
You can use the bitwise-operators (&&, ||) to check on the value. See here.
Upvotes: 0
Reputation: 437336
That monstrous boolean condition describes some common quality shared among a subset of your data objects. Pinpoint that quality and give it a descriptive name.
Then, either expose the value of that quantity through a property on your data object, or else write an extension method that does the same. Finally, replace the existing condition with a use of this accessor.
For example, if the name of the quality is "friendliness" then you might do this:
where model.IsFriendly // property
or this:
where model.IsFriendly() // extension method BusinessRules.IsFriendly(Model m)
Upvotes: 6