How to lower IL nesting depth? - c#

I am giving NDepend a try for 2 weeks now. I still couldn't really figure it out on how to lower ILNestingDepth. I have few methods left marked as "Methods too complex - critical". And as a fix method they suggest to seperate method into smaller methods. But I couldn't fix it that way. Let me show you a method:
First Version: ILNesting Depth of Appropriate = 7
public bool Appropriate ( CompanyQuota available, CompanyQuota used )
{
/// - larger than available or
/// - less than already used area
return !( DiskQuota > available.DiskQuota || DiskQuota < used.DiskUsage ||
UploadQuota > available.UploadQuota || UploadQuota < used.UploadUsage ||
DownloadQuota > available.DownloadQuota || DownloadQuota < used.DownloadUsage ||
PersonnelQuota > available.PersonnelQuota || PersonnelQuota < used.PersonnelUsage );
}
Second Version: ILNesting Depth of Appropriate = 7
public bool Appropriate ( CompanyQuota available, CompanyQuota used )
{
/// - larger than available or
/// - less than already used area
return AvailableFromTop(available) || AvailableFromBottom(used);
}
bool AvailableFromTop ( CompanyQuota available )
{
return !( DiskQuota > available.DiskQuota ||
UploadQuota > available.UploadQuota ||
DownloadQuota > available.DownloadQuota ||
PersonnelQuota > available.PersonnelQuota );
}
bool AvailableFromBottom ( CompanyQuota used )
{
return !( DiskQuota < used.DiskUsage ||
UploadQuota < used.UploadUsage ||
DownloadQuota < used.DownloadUsage ||
PersonnelQuota < used.PersonnelUsage );
}
How does it really work?
What should I really do?

As #Patrick from NDepend team says on the comments this was a false positive report. Hence this question does not need an answer.
For the sake of the community I am keeping this question here with the answer containing only the comment of Patrick, for the "too-lazy-to-read-comments" people.

Related

IF function with && and || at the same time

I want to do IF under serveral condition AND && and OR || on it
i have two range of number
Top1 - Bottom1 and
Top2 - Bottom2
and only executed when Currentnumber is within these two range
am i doing it okay ?
if (OnlyAbove == True
&& (Top1 > Currentnumber || Top2 > Currentnumber)
&& (Bottom1 < Currentnumber || Bottom2 < Currentnumber)
)
{
Statement
}
I'm going to go out on a limb and say: no, you're not doing right on this one - mostly because what your code is currently doing doesn't make sense.
One thing that helps out with stuff like this is to phrase it in common english - so you go from:
if (OnlyAbove == True
&& (Top1 > Currentnumber || Top2 > Currentnumber)
&& (Bottom1 < Currentnumber || Bottom2 < Currentnumber)
)
{
Statement
}
... to ...
if OnlyAbove
AND (CurrentNumber above at least one of the two Tops)
AND (CurrentNumber below at least one of the bottoms)
After all, the stuff between those inner parenthesis is saying "Top1 > current OR Top2 > current" - which really isn't what you're looking for.
Something that'll help out - not only writing code like this, but reading it down the line, is to go a bit overboard with variables. Variables are awesome at helping you document logic, since you can name them very descriptively.
So imagine code that looks like this:
bool betweenRange1 = (Currentnumber > Bottom1) && (Currentnumber < Top1);
bool betweenRange2 = (Currentnumber > Bottom2) && (Currentnumber < Top2);
if (OnlyAbove && betweenRange1 && betweenRange2)
{
Statement
}
... that IF statement starts to look a lot more readable - it's obvious at a glance at what it's getting at. If you're having trouble parsing IF statements, it's not a bad habit to get into. Maybe a bit overkill... but overkill's a lot better than having code you're not sure of what it's doing :-)

if statement with multiple conditions instead of using AND

I been searching for some information about if statements with multiple conditions but haven't found something that corresponds to myquestion.
I was wondering if you could write:
int n = 3
if (3 < n < 20)
{
//do something..
}
rather than doing:
if (n > 3 && n < 20)
{
//do something..
}
The first statement doesn't work for me which i think it should, because it's plain simple.
Maybe someone can give me the correct syntax for doing so or maybe it's just impossible at all and i just have to go with the AND.
To explain why it's invalid:
if (3 < n < 20)
Could be rewritten as:
if ((3 < n) < 20)
Now 3 < n's outcome would be a bool.
So basically you'll get:
if (true/false < 20)
Which is not valid in C#.
Stefan's answer explains why it's impossible.
But here is a workaround, if you don't want to write that pesky && explicit conditions every time - you can create an extension method:
public static class IComparableExtensions
{
public static bool Between<T>(this T self, T low, T high) where T : IComparable
{
return self.CompareTo(low) > 0 && self.CompareTo(high) < 0;
}
}
And use it like this:
int n = 5;
if(n.Between(3, 20))
{
// do your stuff here
}
Please note, however, that this might be confusing - since Between doesn't specify if the compare is inclusive, exclusive, or inclusive in only one direction - so if you compare, say, 20.Between(10, 20) - should it return true or false?
A better approach would require adding another variable to the method, to indicate that:
[Flags]
public enum CompareMode
{
Exclusive = 0,
IncludeLow = 1,
IncludeHigh = 2,
Inclusive = IncludeLow | IncludeHigh
}
public static class IComparableExtensions
{
public static bool Between<T>(this T self, T low, T high, CompareMode mode) where T : IComparable
{
var compareLow = (mode & CompareMode.IncludeLow) == CompareMode.IncludeLow ? 0 : 1;
var compareHigh = (mode & CompareMode.IncludeHigh) == CompareMode.IncludeHigh ? 0 : -1;
return self.CompareTo(low) >= compareLow && self.CompareTo(high) <= compareHigh;
}
}
Now you use it like this:
if(n.Between(3, 20, CompareMode.Exclusive))
{
// do your stuff here
}
You can see a live demo on rextester.
This way, another person reading this code (or even you, 6 months from now) will know immediately, without having to look inside the Between extension method, if between is inclusive, exclusive, or whatever.
Generally it is not possible what you want to do.
but in your logic if you want to perform single liner logic you can use ternary operator.
for eg. you need to assign value of n to variblae result else it should be 0 as default.
int result = n > 3 ? (n < 20 ? n : 0) : 0
it is equivalent to
int result = 0;
if (n > 3 && n < 20)
{
result = n;
}

Evaluate condition irrespective of first outcome

I know this is probably a newbie question, however I need to get a recommendation for the design of this.
I need to evaluate the result of a set of conditions and they must be evaluated irrespective of the outcome of a preceding condition. This brings the case of using regular OR(|) or short-circuit evaluation using ||.
Below is the code that I need to make a design decision about, however the end goal is to be able to evaluate or condition regardless.
private bool checkExistingBPNInSession()
{
var exDirectors = (List<ViewModels.NewContact>)Session["NewDirectorDetails"];
var exTaxConsultant=(List<ViewModels.NewContact>)Session[Resources.Global.NewTaxConsultantDetails];
var exTaRep = (List<ViewModels.NewContact>)Session["NewTaxRepresentativeDetails"];
if (exDirectors.Count() != 0 || exTaRep.Count() != 0 || exTaxConsultant.Count() != 0)
{
var QueryCheckDir = (from x in exDirectors where x.BPN==txtBusinessPartnerIdNumber.Text select x.BPN).ToList();
var QueryCheckTaxConsultant = (from x in exTaxConsultant where x.BPN == txtBusinessPartnerIdNumber.Text select x.BPN).ToList();
var QueryCheckTaxRep = (from x in exTaRep where x.BPN == txtBusinessPartnerIdNumber.Text select x.BPN).ToList();
if (QueryCheckDir.Count() > 0 || QueryCheckTaxConsultant.Count() > 0 || QueryCheckTaxRep.Count() > 0)
{
return true;
}
else
{
return false;
}
}
return false;
}
These parts here have to be evaluated:
exDirectors.Count() != 0 || exTaRep.Count() != 0 || exTaxConsultant.Count() != 0
and this also
QueryCheckDir.Count() > 0 || QueryCheckTaxConsultant.Count() > 0 || QueryCheckTaxRep.Count() > 0
Please, I am seeking the best recommendations.
Thanks guys.
If you want an evaluation done, no matter what, you should use the
|-operator - this will evaluate every condition even if the outcome of the final expression would not change (contrary to ||-operator)
Here is a simple demo using dotnetfiddle

C#: Choosing operator depending on boolean value (in one line)

I'm trying to get away with a slick one liner as I feel it is probably possible.
I'll put my code below and then try to explain a little more what I'm trying to achieve.
for (int p = 0; p < 2; p++)
{
foreach (string player in players[p])
{
if (PlayerSkills[player].streak_count *>* 0) //This line
PlayerSkills[player].streak_count++;
else
PlayerSkills[player].streak_count = 0;
}
}
*(p==0 ? >:<) the comparison operator is chosen depending on p.
Of course what I've written is rubbish. But basically I want to use >0 when p==0, and <0 when p>>0. Is there a nice way to achieve this?
Well, you should use what is most readable, even if it is not as consice. That said...
// Invert the count for all but the first player and check for a positive number
if (PlayerSkills[player].streak_count * (p==0 ? 1 : -1) > 0)
I don't know about slick, but the following and/or combination is one line:
if ((p == 0 && PlayerSkills[player].streak_count > 0)
|| PlayerSkills[player].streak_count < 0)
...
This will only ever do the array index once (due to the p==0 condition occurring first) and so is equivalent to the "ternary" you wrote (albeit a bit more verbose).
p > 0 ? whenGreaterThanZero : whenZeroOrLess ;
E.g.
int p = 1; bool test = p > 0 ? true : false ;
Lets test = True

Check if intersecting within a 1 "block" radius

I have two positions on a 3D system, say [15, 32, 42] and [16, 32, 42]
Is there a easy way to check if they are within a 1 block radius from each other?
This is what I have, but is there a better way of doing it:
if (pos[0] == pos1[0] / 32 || pos[0] == pos1[0] + 1 || pos[0] == pos1[0] - 1)
{
if (pos[1] == pos1[1] || pos[1] == pos1[1] - 1 || pos[1] == pos1[1] + 1)
{
if (pos[2] == pos1[2] || pos[2] == pos1[2] + 1 || pos[2] == pos1[2] - 1)
{
Thanks,
David
You can use Math.abs(pos[0]-pos1[0]) <= 1 to check if two coordinates in the same plane are at most 1 apart.
So all in all, your code could look like this:
if( Math.abs(pos[0]-pos1[0]) <= 1
&& Math.abs(pos[1]-pos1[1]) <= 1
&& Math.abs(pos[2]-pos1[2]) <= 1 )
{
Within a 1 block radius
}
Note that I do not understand why you divided your first equation by 32. I did not include that in this answer.
Note also that this solution makes things a little more readable, but that yours is correct too.
I haven't done this in c# but in Java I use JTS. http://geoapi.codeplex.com/ seems to provice the same functionality in c#. Then you will represent your points as Point objects and have all sorts of useful geospatial functions to use.
But for this case, are you looking for the "as the crow flies" distance, which is just pythagoras, or the "walking distance", which would involve finding the shortest valid route in a directed graph of footpaths?
Julian

Categories