Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 621 Vote(s) - 3.46 Average
  • 1
  • 2
  • 3
  • 4
  • 5
C# - Code density saves lives

#1
I'm sure we've all seen something like this before....

[Image: simple-java-programs-15-728.jpg?cb=1269419230]

Yes, we all cringed at that. There's a few issues with it, but the most important of which is that there is actually very little code here. Nothing really does anything, it just takes up lines (even with the painful practice of same-line bracing). So, how can we remedy this?

Well, there are a few ways and C# has some neat tricks to help us, I'll cover 3 of these:

  1. reduce declarations
  2. combine if statements
  3. pattern switches

1. Reduce declarations

This one may sound redundant, but C# does have some help here. Modern versions of C# have the ability to declare variables as they are being used, with either the is our out keywords. I'll give you two examples to demonstrate this point (it really is this easy).

Let's first look at this example of some dummy code that would check if a Stripe subscription is active, and if so, do something with it:

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

The first thing we can do, is bring that if statement inside of the using, and get rid of the braces there (the if block is treated as a single line). When we bring it in, we don't just want to drop the if right below the assignment line though, that would be pointless. Instead, we can actually move the assignment inside of the if statement, since the variable subscription is already declared. To do this, we just wrap the entire assignment in an extra set of parens and then introduce a check.

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

When moving it in, we can usually check against null if we're planning on using anything within it (I added a writeline to demonstrate). Because we know the first term will either short circuit or be non-null, we can remove the null-conditional check on the Status member. As you can see, doing that alone has reduced the size of our function from 10 lines to 7, but that's not as simple as it can get either..
What if we could get rid of that pesky declaration line up front, and make the code self documenting in the process?
We actually can do this, with the [is] keyword, which only works in our if statements, and acts a lot like how we brought our instantiation inside of our if statement.
To go about it, all we have to do is
  1. Remove the extra parens
  2. Remove everything except of what's to the right of the equals (and get rid of the equals)
  3. Copy the declaration line after the instantiation, separated by is


Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

And of course in this case, I've re-added the null-conditional. This probably isn't required, but I usually add it just in case it might pop out null. Our final function is now 6 lines, a 40% reduction in number of lines over the original, while still functioning exactly the same.

Now let's look at another example. Let's say you have a database, and in a table one of your fields is a datetime, but some pesky database administrator has forced the column to type varchar and made it a non-nullable field (empty string used instead of NULL). This actually happens to me quite a bit with work. Let's also say that your code depends on it being a DateTime? (nullable). We can write up a pretty simple function to convert between the two:

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

Of course, I left out the braces and a completely useless else statement on this one, I don't think you needed to see it. What we have here is 7 lines of code that's just taking up screen space. What if I told you this could be reduced to just a single line. Well, it can.
Just like with the is keyword, we can modify our call to TryParse to declare the variable parsed for us, and get rid of that declaration.

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

Ok, now we're down to 6 lines, but we can still get it down further, by making use of the ternary operator:

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

In doing so, we'll need to keep the compiler happy and cast one of the operands on the ternary. I tend to cast the null value to the return type so it's not ambiguous to future developers. Now we're down to 4 lines, it can't get any smaller, can it?
Yes, it can, and I'm not talking about just putting it all on one line. C# actually has a built in operator for implicit returning. I discussed it briefly in my

[To see links please register here]

thread. We simply use => instead of brackets, and drop the return keyword.

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

As you can see, we're now down to just a single line. That's an 86% reduction in what I'd call wasted lines.

2. Combine if statements
This one is pretty self explanatory, I'm sure we've all seen code that's similar to the following:

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

This is 4 lines when it ought to only be 2. We don't need to nest this, because there isn't anything else it could do. We can just simply combine these two things, and drop the braces.

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

You do really need to be careful when doing this though, there are cases where you do NEED to match on that clause. For example, if there is another else if clause below that, you'll need to add

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

to that statement in order to retain the functionality of the else if. For most scenarios though, you'll find you have unnecessary nested if statements that can be reduced down to a single statement.
I know this was a short and potentially obvious one, but trust me it needed to be said. I pulled the original example out of a current codebase that I wrote, and I like to think I have an excellent eye for keeping good code density.

3. Pattern switches

This one has been by far the most useful thing for me recently. Let's say you're doing something that switches out the graphic depending on the device OS and the theme. You might have code similar to the following:

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

I don't need to tell anybody that's a lot of code that gets wasted. Only the far inner cases actually do anything. If we ignore the enumeration definitions, we've got 64 lines of code....It doesn't even fit on one screen @1080p with smaller than normal font size. This would get to be an incredibly annoying thing to maintain if this was anything larger than just an example.
Well, C# is again here to the rescue, with pattern switches. This is a new feature that's only available in C#8, but if you can update you should if only for this one feature. Before we get into the big example, let's look at a much smaller example and I'll explain how it works and how to convert them:

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

So here, we're only dealing with one switch, but there's a lot going on here that doesn't have to be. It would be nice if we could get rid of some of those braces, and if we could stop typing case and return. Thankfully, there's a new shorthand for switches like this. We can simply reverse the order of that first line, get rid of case and return, replace the semocolons with comas, and replace the colons with =>. The result is the following:

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

As you can see, it's a whole lot easier to read. I should mention that underscore is the equivalent of the default keyword. But, we still haven't gotten rid of any of the braces. Thankfully, since that switch is now a single statement, we can drop the return and method braces.

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

We're now down to 7 lines, from 10, a 30% density improvement. Let's go ahead and convert our original example using these:

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

We're now down to 58 lines (9% density improvement). The entire function now fits on my screen, but it's still got a lot of jumbo in it. We could eliminate the breaks by simply converting the next level up to pattern switches as well:

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

Ok, now we're down to 54 lines (15% density improvement). But, what if we went another level up, could we reduce it any further?

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

Yep, we shaved another line off of it. We now have a 17% increase in density. We're not done yet though. We have a lot of duplicated default cases, as well as way too many sets of braces. Well it turns out that we don't have to nest our switch statements, we can combine them all into a single one. We do this simply by creating a tuple out of the whole set. We can just wrap multiple condition layers into a single case by putting parens around the combination of selectors. Rather than describe it more, I'll just show you the final result.

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

The way this works, is it will go through each one and as soon as it matches one it will return its value. We simply cover all cases and at the end we include an all wildcard that returns null.
Our final line count is 21 lines (67% density improvement). There is no limit to how many patterns you use, and you can place the wildcards in any position within the selectors or case list, allowing you to make very specific or general case statements that match a variety of parameters without having to nest your switch statements and with minimal code that doesn't do anything.

To demonstrate this, we can even make this smaller since this follows a format (I did it this way to demonstrate the uses, but this is a simple example).

Hidden Content
You must

[To see links please register here]

or

[To see links please register here]

to view this content.

I did this to demonstrate that you may not always need to be so specific with your statements. You can see that everything follows a specific format, and so we can just program our switch to use that format. This one is only 6 lines long (91% density improvement). Make sure you look for switches that can be simplified in this way. Sometimes converting it to a multi-parameter pattern switch helps you identify what the pattern is so you can simplify like this. Don't be afraid to do it.



Well, I hope you guys enjoyed this, please feel free to leave your comments, sample code you'd like to see neat ways to simplify/reduce, or other topic ideas below.
Reply

#2
Quote:(11-05-2019, 06:03 PM)Drako Wrote:

[To see links please register here]

It's nice to see you're still making tutorial threads like these.

I do feel like C++ is getting left behind now, only because it's an older language. I don't see a lot of it anymore. So I'm transitioning to other ones now. C# would probably be a better alternative for me.

I've never been a big C++ fan myself, at heart I'm a C guy, but for the majority of the commercial software I write C just isn't worth the budget. My clients are willing to take the performance and security hits to use C# instead of paying me likely 3 times as much to do it in C.
Reply

#3
It's nice to see you're still making tutorial threads like these.

I do feel like C++ is getting left behind now, only because it's an older language. I don't see a lot of it anymore. So I'm transitioning to other ones now. C# would probably be a better alternative for me.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through