Recursive code is hard to understand - need to simplify [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I have an entity and I can have InvoiceLine on top of that, then you can credit that invoice line infinite no of times. but only main InvoiceLine have reference to original entity.
I am using recursion to get the original entity , but the code is not that readable
private static PermanentPlacement PopulatePermanentPlacement(InvoiceLine invoiceLine)
{
PermanentPlacement permanentPlacement;
var creditReissue = invoiceLine.CreditReissue;
do
{
permanentPlacement = creditReissue.InvoiceLine.PermanentPlacement;
if (permanentPlacement == null)
{
creditReissue = creditReissue.InvoiceLine.CreditReissue;
}
} while(permanentPlacement == null);
return permanentPlacement;
}
Is there any way I can make this more readable and simplify ?

I think the answer by René Vogt shows the best way to simplify this code. But there are others. For example, consider moving the loop to a helper function:
static IEnumerable<Reissue> CreditReissues(Reissue original)
{
var current = original;
while(true)
{
yield return current;
current = current.InvoiceLine.CreditReissue;
}
}
And now you don't ever need to write a loop again in order to use an infinite sequence of credit reissues:
private static PermanentPlacement PopulatePermanentPlacement(
InvoiceLine invoiceLine)
{
return CreditReissues(invoiceLine.CreditReissue)
.Select(cr => cr.InvoiceLine.PermanentPlacement)
.First(pp => pp != null);
}
That is: take the infinite sequence of credit reissues, turn it into an infinite sequence of permanent placements, and return the first non-null one in the sequence.
Notice how by changing the loop into a sequence, we can now describe the operations we want to perform on the level of sequences and not on the level of statements and variables.
Incidentally, you say -- twice -- that you are using recursion in the original code, but you are not. A recursive solution would look like this:
private static PermanentPlacement PopulatePermanentPlacement(
InvoiceLine invoiceLine)
{
return invoiceLine.PermanentPlacement ??
PopulatePermanentPlacement(
invoiceLine.CreditReissue.InvoiceLine);
}
You should not use a recursive solution for a potentially unbounded loop because C# is not guaranteed to be tail recursive, and therefore can blow the stack.

I would shorten the code to:
private static PermanentPlacement PopulatePermanentPlacement(InvoiceLine invoiceLine)
{
var creditReissue = invoiceLine.CreditReissue;
while(creditReissue.InvoiceLine.PermanentPlacement == null)
creditReissue = creditReissue.InvoiceLine.CreditReissue;
return creditReissue.InvoiceLine.PermanentPlacement;
}
This does the same as your code, except that it accesses PermantPlacement of the final InvoiceLine an extra time. So if this property getter does more than just returning a value, this modification may not be valid.

Your code seems pretty clear and readable to me. René Vogt's answer is about as short as you could make it without changing the logic but I have a gut feeling that what you really want might be this:
private static PermanentPlacement PopulatePermanentPlacement(InvoiceLine invoiceLine)
{
var creditReissue = invoiceLine.CreditReissue;
while (creditReissue.InvoiceLine.CreditReissue != null)
{
// Get the last credit reissue
creditReissue = creditReissue.InvoiceLine.CreditReissue;
}
return creditReissue.InvoiceLine.PermanentPlacement;
}
It does change the logic a bit, please validate that it is equivalent.

Related

Neater Way to Set One of Two Variables to a Certain Value Based on a Boolean? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I've noticed that I use this pattern a lot in my C# code. (It's within a Unity script, if it matters.)
if (someBoolean) {
firstVar = 10;
} else {
secondVar = 10;
}
My question is as simple as can be--is there a way to make this pattern take up less space than the five lines it does? Perhaps even make it inline? I thought ternary operators might do it, like so...
(someBoolean ? firstVar : secondVar) = 10;
...But it quickly became apparent ternary operators in C# don't work like that.
I also considered creating some sort of global function in a static class that I could simply pass the appropriate variable to, but it's the pattern that is frequently repeated, not necessarily the operation. So the function method wouldn't work for where I've repeated this pattern elsewhere, with different operations, like so...
if (anotherBoolean) {
thirdVar += exampleVar;
} else {
fourthVar += exampleVar;
}
Of course, I could just do this...
if (someBoolean) { firstVar = 10; } else { secondVar = 10; }
...But that's kind of icky, isn't it? Either way, I'd appreciate any advice you could provide. Many thanks.
Just use if/else. You--by which I mean I--are/am overthinking it.
You can use Destructuring assignment (C# 7) to make it into single statement:
(firstVar, secondVar) = someBoolean ? (10, secondVar) : (firstVar, 10);
Whether it is more expressive than simple if is up to debate, but it gives you single statement at least. Can be good option if the rest of the project actively uses "destructing" and new C# 7+ features.
Unlike suggestion to use helper function with ref arguments destructing can be used for arrays, lists and properties:
(list[0], list[1]) = someBoolean ? (list[0], 10) : (10, list[1]);
(x.SomeProp, x.OtherProp) = someBoolean ? (x.SomeProp, 10) : (10, x.OtherProp);
If this is a frequent occurrence, you can make use of extension methods as well.
class Program
{
static void Main(string[] args)
{
var firstVar = 1;
var secondVar = 2;
true.SetValue(ref firstVar, ref secondVar);
false.SetValue(ref secondVar, ref secondVar);
Console.Read();
}
}
public static class BoolExtensions
{
public static void SetValue(this bool bVal, ref int first, ref int second)
{
if (bVal)
first = 10;
else
second = 10;
}
}

Accessing a property through reflection returns a different value [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Ok, as my original question seemed a bit ambiguous because I was asking for a general question about the C# language, but showing part of a particular example where I was having a problem with it, I'm going to try to rewrite so that it is clearer that my question is about the C# language, not about my particular problem.
I currently have a property (several, in fact) of a class, that return a different value depending on whether you access them directly by code, or using reflection. This is what happens when I access the property using the immediate console of VS:
> SelectedLine.QtyOutstanding
0
> var prop = SelectedLine.GetType().GetProperty("QtyOutstanding")
> prop.GetValue(SelectedLine)
8
Regardless of how the property is defined, what is the difference, in C#, between both ways of accessing the property?
Shouldn't they both run exactly the same code in the setter/getter, if there is one?
(Considering that GetType() returns the same type as the variable is declared as)
I found a way to produce this, maybe your case looks like that?
If your SelectedLine is accessible via interface, and your class has an explicite implementation of that, but also has a public property with the same name, this could lead to different results.
Example
class Program
{
static void Main(string[] args)
{
var SelectedLine = (ILine)new Line(8);
Console.WriteLine(SelectedLine.QtyOutstanding); // 0
var prop = SelectedLine.GetType().GetProperty("QtyOutstanding");
Console.WriteLine(prop.GetValue(SelectedLine)); // 8
Console.ReadLine();
}
}
class Line : ILine
{
public Line(int qtyOutstanding)
{
QtyOutstanding = qtyOutstanding;
}
public int QtyOutstanding { get; }
int ILine.QtyOutstanding
{
get
{
return 0;
}
}
}
interface ILine
{
int QtyOutstanding { get; }
}

General Purpose Equality Checker [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm maintaining a codebase and I've found two extension methods, dealing with checking the structural equality of objects, which I do not like at all (one invokes the other):
public static bool IsObjectEqual<T>(this T obj, T obj2)
{
foreach (var pi in obj.GetType().GetProperties())
{
var enumerable1 = pi.GetValue(obj, null) as IEnumerable;
var enumerable2 = pi.GetValue(obj2, null) as IEnumerable;
if (enumerable1 != null)
{
foreach (var item in enumerable1)
{
if (enumerable2 == null || !((object[])enumerable2).Contains(item))
{
return false;
}
}
}
else if (!IsPropertyInfoValueEqual(pi, obj, obj2))
{
return false;
}
}
return true;
}
private static bool IsPropertyInfoValueEqual<T>(PropertyInfo pi, T obj, T obj2)
{
var val = pi.GetValue(obj, null);
var val2 = pi.GetValue(obj2, null);
if (val != null && val2 != null)
{
return val.Equals(val2);
}
return (val == null && val2 == null);
}
The problem is, I'm having trouble coming up with a scenario where I think they will fail, or cause problems. I know it in my waters that they are wrong, I just can't put my finger on it.
I've always used IEquateable<T> when implementing equality checking, so the absence of any of the framework classes/Interfaces which deal with equality is one thing which invokes my spidey senses. I realise this method is trying to be a generalised, reflection-based approach, but it makes me nervous (as mentioned).
Can anyone see a legitimate problem with these methods?
Edit
Big legitimate problem with the methods. The cast to object[] results in an InvalidCastException.
There could be others, but I see two main problems with this code:
Reflection is expensive. Really expensive. To use it on such a large scale for something as simple as equality checking is just a bad idea. The code doesn't even cache the object graph so its having to do the full reflection every time. Under fairly common scenarios I can see this method being a performance bottleneck.
If members are IEnumerable, the code won't work as expected. Everything else is compared with reflection, but the collections are compared using Contains. This will do simple reference equality (for reference types at least) and doesn't reuse the reflective method. This would likely lead to undesirable results for the users of this method.
Implementing IEquatable and friends is a much faster, and safer, approach. The implementer gets to explicitly decide how the comparison works, and you don't need any reflection.

Common Code Convention for not equal in conditional statements [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I've been coming across not equal != or !condition in conditional statements ever since I started programming. Maybe it's because my brain is pre-conditioned in the English language to overthink multiple negation. But I have been wondering, is there a common development community accepted practice when it comes to evaluating for true in conditional statements? Or rather, the way I see it sometimes: evaluating for not false.
Maybe there are exceptions where != cannot be completely unavoidable?
For Example:
This might be a very simple and trivial, but is this preferred
string myStringVar = "dogs";
if (myStringVar != "dogs") //In my mind, "False this is not true"
{
//code
}
else if (myStringVar != cats) //In my mind, "True this is false"
{
//code
}
Or is this preferable
if (myStringVar == "dogs")
{
//"True"
}
else if (myStringVar == "cats")
{
//"False"
}
Then there's
bool MyBoolMethod()
{
return false;
}
if (!MyBoolMethod()) // True this method does not return true
{
//code
}
This is a very trivial and simplified example, I just want to know how to write readable, maintainable code. Does anyone else have a somewhat difficult time reading conditionals like this or is it just me?
"None of the above."
Since you're using strings, the assumption is that myStringVar can be anything. If I say:
string myStringVar = "Aardvark";
Then your first example, it will run the myStringVar != "dogs" section of code; In the second example, neither will be executed. So they're not equivalent pieces of code.
The only way they would be equivalent is if you were using Enums (in which case I would suggest using a case statement).
In your third example, it would depend on what MyBoolMethod() was named, and how easy it was to understand by a future coder. To use an example,
bool isDog()
{
return false;
}
is is easy to understand. The question then becomes is
if(!isDog()) ...
more clear than
if(isNotDog()) ...
I would argue that the first is more clear than the second. There are other situations, however, where that is not the case.
Equality and inequality are just something one needs to get comfortable with and choose in context. If the logical problem requires looking to test against equality use equality if it is looking to disqualify use inequality.
The readability and maintainability can be reinforced through good design as you started to allude to with your mybool method.
Exmaple
public class Animal
{
public static Enum AnimalType
{
Dog,
Cat
}
private _animalType;
public Animal(Enum AnimalType type)
{
AnimalType = _animalType;
}
public bool isOfType(Enum AnimalType type)
{
return _animalType == type ? true : false;
}
}
public someothermethod()
{
//doing inclusion
If(MyAnmialObject.isOfType(Animal.AnimalType.Dog))
{
//if type matches
}
//Doing exclusion
If(!MyAnmialObject.isOfType(Animal.AnimalType.Dog))
{
//if type does not match
}
}
You still have to get used to inequality but you know it is checking for isOfType and the named type.

Is it readable or non-effective in C# to declare conditions before using IF [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
When writting codes, using if by following way
int something = 5;
bool possible = false;
if( something>0 && !possible){
doSomething();
}
and
int something = 5;
bool possible = false;
bool condition1 = something > 0;
bool condition2 = !possible;
if( condition1 && condition2){
doSomething();
}
Which is more readable?
Which is more effective?
I assume 2nd is better when case like
if( Something > (SomeOtherThing + SomeSomeThing) && !Something.Something.Possible)
I know this doesn't directly concern with c# but want to know especially in c#!
There is no hard and fast rule, but quite often the code can be much more readable if you extract to speaking variable names or method calls. In the following example the condition is absolutely clear.
bool UserIsAdmin() { ... }
bool UserOwnsItem() { ... }
bool UserMayAccessItem {
return UserIsAdmin() || UserOwnsItem();
}
// ..
if (UserMayAccessItem()) {
// do something here
}
On the other hand there certainly may be simple cases where adding variables does not increase readability.
It basically is a matter of style and preference. Just keep in mind that the code should be easily readable and speak for itself.
The first option is preferable, not only because of shortcut evaluation, but also for maintainability.
I guarantee you that you or someone else will eventually change the conditions, without bothering to adapt the variable names, too, for example.
It is non-effective.
When condition1 is false, it is not required to calculate condition2 in your example. Sometimes this calculation eats resources (request to DB for example). In this case 2nd option is non-effective.
However it is readable, particularly when you name condition variables in more convenient way, for example:
bool somethingIsPositive = somithing > 0;
bool itIsImpossible = !possible;
if(somethingIsPositive && itIsImpossible)
...
Also you can leverage Lazy class (if you use C#) to not claculate condition2 all the time (even when condition1 is false), so this is really more readable and hasn't performance problems (when condition2 takes time to calculate, not in your case :) ):
int something = GetNumber();
bool possible = GetPossibility();
var somethingIsPositive = new Lazy<bool>(() => something > 0);
var itIsImpossible = new Lazy<bool>(() => !possible);
if( somethingIsPositive.Value && itIsImpossible.Value){
doSomething();
}

Categories