Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
These are a few things (in no specific order) I found out during many hours of work, discussions with colleagues and a-ha moments. And I would like to share them with everyone and don’t be ashamed if you don’t know some or even all of them. In some cases it took me years to get to know them. So embrace them and it might make you a better .NET developer.
Geeky stuffNumber 1: Order of logical operations (AND and OR)
Starting with an easy and powerful one. This can create you a lot of headaches if not handled properly: && (AND) is more powerful than || (OR). Lets take a few examples to see what that means and how it can affect your code:
bool result;
result = (true || true) && false; //this gives false
result = true || (true && false); //this gives true
result = true || true && false;// what will be the result of this?
Like I said above AND is more powerful than OR, which means it will be run first, even if it is the second operation. So the third case after we do the AND operation will become: result = true || false so it will give you true. So it is exactly the same with the second operation. Now my suggestion is to always use parenthesis for the order of operations to look more clear.
Number 2: Out parameter always changes value
Here is some simple code and a simple question:
int testParameter = -1;
Int32.TryParse(“abc”, out testParameter);
What will the value of testParameter be after the TryParse executes?
Easy to try for yourself, just put this in console application and display the value of testParameter. If you expected it to be -1 then you are wrong. Even if the TryParse will not succeed, the value of the int will become the default value, so it will be 0 (zero). This is what MSDN says about the out parameter: This parameter is passed uninitialized; any value originally supplied in result will be overwritten.
Number 3: Enums can have extension methods
We had a big Enum in code with the possible values of a variable. I am not getting into details why we need it or if it was the best choice for us, it’s not the case here. Lets say it looked something like this (trust me, it was bigger, this is just a smaller similar example):
enum Day {Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};
Now imagine that if you would like to see if it is weekend, your code will be similar to this:
if (dayParameter == Day.Sun || dayParameter == Day.Sat) ….
So I created a method called IsItWeekend(dayParameter). Then one colleague said why don’t we create an extension method, instead of having the above method in every class we might need it?
And to be honest I didn’t think it would be possible to create an extension method on Enums, but 2 days later I came back to him and said: ‘sorry, I was wrong, it is possible to do it’. And I found that it really is powerful because the most used alternative is to create a Helper class and I don’t like them at all. I am not getting into details on how to create such an extension method because there is a very good article on MSDN about it. I believe it is more important to remember that it can be done.
Number 4: Use HashSet for distinct items
I find this code quite a lot in many projects:
List<string> uniqueItems = new List<string>();if(uniqueItems.Contains(parameter)){ uniqueItems.Add(parameter);}
So is there a problem with this? It works, but Contains performs a linear search on the list and that is O(n). Which can translate into performance issues in production if you end up having many of these (usually big CPU usage). Until .NET 3.0 people were creating Dictionaries with the key collection used for distinct lists and with the values set as NULL. But since .NET Framework 3.5 we have a new class called HashSet<T>. This is a collection without any duplicate elements and Contains method is O(1) operation. So our code quickly becomes:
HashSet<string> uniqueItems = new HashSet<string>();if(!uniqueItems.Contains(parameter)){ uniqueItems.Add(parameter);}
Even more, we can remove the Contains call because Add will not add the element if it already exists, it just returns false (or true if it will be added). So again the code becomes like this:
HashSet<string> uniqueItems = new HashSet<string>();uniqueItems.Add(parameter);
Number 5: Many value types don’t live on the Stack
Value types are allocated on the Stack and reference types are allocated on the Heap. That’s what we learned, that’s what we say in interviews and we get away with it. Probably a lot of .NET books that are for beginners are saying this, so we read it from our first steps with C#. But it is wrong, it is just a myth, there are so many value types saved on the heap and here are two important examples of when that happens.
- If the value type is a instance variable of an object then it gets saved on the Heap. Simple because that is where the whole object lives, so that’s where the value types get allocated too.
- Another case is for static variables: a value type static variable is allocated on the Heap. And it makes sense because there is only one instance of that variable.
So what is the difference between value types and reference types, you might ask? That’s very simple: value types are passed by value (even if it is an instance variable of a reference type) while reference types are passed by reference. Which means that next time in an interview you can give a more accurate answer.
Number 6: Response.Redirect on out of process sessions
This is one of my favorites because I found it around 2014 when we wanted to change an existing application to use out of process session. Our aim was to support multiple servers, but we didn’t want to use sticky sessions — we were deploying on AWS so using sticky sessions meant loosing all the advantage of auto scaling. We did learn a lot from going out of process with the session and using Response.Redirect was one of the outcomes. Lets say we have some simple code like this:
Session[“FlowId”] = Guid.NewGuid();//more code goes hereResponse.Redirect(Url.Action(“Account”, “Login”));
This works perfectly when the session is in process, but when it goes out of process that Session[“FlowId”] item will not get saved. It happens because Response.Redirect throws a ThreadAbort exception and because of that the thread never gets to the part where it saves the Session object in the outside store. When the Session is used in process all the changes are done on spot, which means that throwing the exception doesn’t affect the saving.
So what is the solution for making it work? Simple, Response.Redirect has an overload that takes a second parameter endResponse, just pass false and the exception will not get thrown. It is even recommended to set it to false because of performance reasons.
Session[“FlowId”] = Guid.NewGuid();//more code goes hereResponse.Redirect(Url.Action(“Account”, “Login”), false);
Number 7: A generic type creates different classes
We have the following class:
public class GenericCache<T>{ public static int ctorCalls = 0; private List<T> list; public GenericCache() { ctorCalls++; list = new List<T>(); } }
The implementation is pretty dumb, just for education purposes (so don’t ask me why ctorCalls is a public field). But such a class can be found quite frequently in a big application. There always has to be a Cache class (so you can save expensive I/O calls) and it will be a matter of time until it becomes generic (because you will use it for many of your classes).
GenericCache<string> genericCache = new GenericCache<string>();GenericCache<int> genericCacheInt = new GenericCache<int>();Console.WriteLine(GenericCache<DateTime>.ctorCalls);
In the lines above the constructor of the generic Cache class is called twice and then we want to print the value of ctorCalls to the console.
So what value will it display? Well if you say 2 then you are wrong. It is what generic does behind the curtains: GenericCache<string> will be a different type (class) than GenericCache<int> and GenericCache<DateTime>. Which means the static variable ctorCalls will have 3 instances, one for each generic type. So the value displayed to the console will be 0.
That’s it and I hope it is helpful to you. And please leave a comment if you know other interesting things that should be on the list of gotchas for .NET/C# code.
7 things you didn’t know about .NET code was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.