9 tips in the .NET world

Cosmin Vladutu
Dev Genius
Published in
3 min readJan 9, 2024

--

Reason

I’ve seen a lot of “tips and tricks” articles, lately in the realm of DotNet, and it reminded me of the positive response my previous article, “5 C# features that most probably you didn’t know about”, received. Encouraged by the interest and feedback, I’ve dedicated some time to writing this article and I hope it will have the same quality for you all.

Tips

  1. EntityFramework .AsNoTracking() thingy. With this, thing you can optimize your app and tell your context: STOP tracking my entity, dude! Disclaimer: If you need to mutate the entity (update, delete, insert) you will need to attach it to the context and set its correct state, but if you just need to get it, you don’t need the context to look over the fence on what you’re doing with it. And think about grabbing an aggregate or just a big entity, from which you want only to return to the caller 3–4 properties…
context.Set<EntityExample>().AsNoTracking()

2. If you haven’t used EF for quite a while you probably don’t know that nowadays you have FirstAsync (FirstOrDefaultAsync) and SingleAsync (SingleOrDefaultAsync), in System.Data.Entity namespace -> QueryableExtensions class. How cool is that now?

3. Use ToQueryString() extension when you investigate/debug performance issues. It might be the “window to a magical world”.

var sqlQuery = context.YourEntities.ToQueryString();

4. AsReadOnly method of a list. If you are working with a large collection and even a small optimization makes a difference, then you should think about trying this one out too. This helps you to get a read-only view of your collection and ensures you that it can’t be changed.

5. Register Generics. Let’s say you have the next interface:

public interface IGenericRepo<T> where T:class
{
Task<T> Get(int id)
}

You can now easily register (now meaning after .net6) in the startup:

services.AddScoped(typeof(IGenericRepo<>),typeof(GenericRepo<>))

where of course the GenericRepo is the generic implementation of the IGenericRepo.

6. CORS at the Api level. The options that you can add are:

  • AllowAnyOrigin: This allows requests from anywhere.
  • WithOrigins: This allows requests from specific origins. (You can specify one or more origins as input to this)
  • AllowAnyHeader: This allows requests with any header.
  • WithHeaders: This allows requests with specific headers. (You can specify one or more headers as input to this)
  • AllowAnyMethod: This allows requests with any HTTP method/verb.
  • WithMethods: This allows requests with specific HTTP methods. (You can specify one or more methods as input to this)
builder.Services.AddCors(o=>
o.AddPolicy(name: "test"),
builder =>
{
builder.WithOrigins("http://www.mysite.com");
builder.AllowAnyHeader();
builder.AllowAnyMethod();
}
)

7. You can return an empty enumeration. You are not limited anymore to null or needing to instantiate a list of something.

IEnumerable<int> test = Enumerable.Empty<int>(); 

8. For some reason people still don’t know how to use GetType() and typeOf(). Let’s see the difference:

  • typeOf gets the type from a class while GetType gets it from an object
  • typeOf gets the type on compile-time while GetType on runtime.
string test = "myTest";

Type t1 = typeof(string);
Type t2 = s.GetType();

// t1 == t2 will return true
object obj = "myTest";

Type t1 = typeof(object); // will return object
Type t2 = obj.GetType(); // will return string

// t1 == t2 will return a big false

9. The secret secret of the sealed. This is the keyword that blocks everyone from inheriting from your class. Alright, and now, what's its secret? Well, even if no one uses it, the secret is that this gives you a little boost in your performance level. Of course not you won’t get a lot, because if that had been the case, everyone would have used it.
Without any testing and stuff, if you don’t believe me, just think about it: When you call a normal object, the runtime must determine which method is executed by checking the type of the object and searching up the inheritance hierarchy until it finds your method, put it into a list, and continue until the end. This was it ensures that you don’t have a conflict. If you give a sealed class, it doesn’t need to worry about derived classes overriding members and so on, so the number of computations is way less.

--

--