The coding conventions I use for C# and why I use them



Become a Patreon and get source code access: https://www.patreon.com/nickchapsas Check out my courses: …

31 Comments

  1. Hi Nick!
    At the end of the video there is a method 'public async Task<User> GetUserAsync()' which returns the result of awaiting of '_userService.GetByIdAsync(Guid.NewGuild()'.
    This is very common scenario. But will it be better or worse or the same if the method will be like: 'public Task<User> GetUserAsync() { return _userService.GetByIdAsync(Guid.NewGuild()); }'?

  2. I find it astonishing that most C# developers would shudder at the idea of using Hungarian notation to denote the type of a variable, but the moment they want to denote its scope, they tag member variables with an underscore; this is equally as bad! The mistake you made was at the moment you said "…if the method is quite big…" – Methods should NEVER be big; "The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that." – Uncle Bob Martin (Mr "Clean Code"). A variable's name is no more responsible for denoting its scope (underscores) than it is responsible for denoting its type (Hungarian notation). As someone who also codes in Java and Kotlin, I can only assume that you don't follow the same underscore convention in those languages, simply because it's not the accepted convention, whereas it is in C#…but it's still wrong.

  3. Enum names should be singular when their intent is to be used as a singular value (i.e. ConsoleColor), but should be pluralised when their intent is to be used as multiple values (i.e. BindingFlags)

  4. I awalys name my methods and properties with lowerCamel to distinguish them from Unity's methods + distinguish them from ClassUpperCamel. No more of this insanity:

    public Engine Engine;

    Engine.Engine.Engine();

  5. I've never understood why "everybody" puts attributes on the top of the class. The future user of the class won't care about the internals, actually nobody should except the author, and then maybe at the beginning of its building. Actually the future user of the class will be firstly interested on the constructor. I don't know, maybe I'am missing something big, but I don't get it. I think it is something that started with the Java coding style, and C# adpoted. However, there are various coding style guides predating C# that differ, such as: https://users.ece.cmu.edu/~eno/coding/CppCodingStandard.html

  6. I always prefer using this. instead of _ for the reason that they are easier to spot and select.
    Another reason is that _ feels like an old custom and the code looks more messy.
    I took time to decide which one to stick to, and I went for this.

  7. If you arent used to using var in c# think of it this way: you dont want to be declaring the type of an object in two places if possible, because if you go back and want to change to another type/interface, you dont need to rename mulitple places. Also it is less code 🙂

  8. I also always use

    var persons = new List<Person>();

    instead of

    List<Person> persons = new List<Person>();

    But since C#9 I've switched to

    List<Person> persons = new();

    Nice and short, just like var, but still the type is clear.
    Everybody wins.

  9. Didn't know an "implicit operator" was a thing. But then again, I didn't know lots of things were a thing until I watched your videos.

    Regarding the var type. The official C# conventions from Microsoft state that if you can't tell what the type is from the right side of the assignment, then you should use the explicit type.

  10. When I am naming things, (serializing JSON into a model in c#) resharper hates the naming because it isn't Pascal. The name is usually lowercase because it is coming from a JavaScript style object. My model classes always have to use the ignore naming comments for resharper.

  11. I agree with just about everything you said here (and we use them with our project at work) except for "var". I personally hate the use of var for just about anything except when returning anonymous objects from a LINQ query. We spend so much time with standards for variable and method names so developers can easily tell what something is, but for some reason when it comes to declaring variables we are ok with making it generic and having to do something to see what it is. But…. that's just me. And other members on my team do not agree, so we don't have any standard around it's use. But as always, great video!

  12. I tend to agree with using var where possible. I program more Rust than C# at my job, but the same trade-offs seem to apply to both. FYI, Rust variable declarations go like this:

    let userId: Guid = …; // explicit

    let userId = …; // implicit

    In Rust and C# 9.0 there are also target-typed value expressions, for example:

    List<uint> nrs = new(); // C#

    let nrs: Vec<u32> = empty().collect(); // Rust

    (This is not the normal way to create an empty Vec<u32>, just an example of target-typing (because new is not a keyword in Rust). "vec!()" or "Vec::new()" are the normal ways. But collecting the empty iterator works for many types, "let map: HashMap<u32, u32> = empty().collect();" is another example.)

    The question that I struggle with is this:

    If I have to choose between a target-typed place-expression or a target-typed value-expression, what should I do, any why?

    I have not been consistent with this, and cannot decide on a preference either. Often I suspect that the ambiguity will go away when I refactor later that day, but it would be nice to have a guideline to follow.

    (I think that C# might use the name "L-Value" for place-expressions and "R-Value" for value-expressions, like C and C++ do. I'm not sure what terms C#-programmers are more familiar with.)

    The C# example of my question would be this:

    var foobar = new(); // ambiguous

    var foobar = new T(); // option one

    T foobar = new(); // option two

  13. Great material as always. Even though I already follow and mentor most of the practices you use, I still watch your videos to learn something new or challenge my thinking.

    One change I would suggest is to the service layer. I'm always uncomfortable seeing the service layer in the same project as other layers. I much prefer a separate project for each service. It finally clicked for me why that is…

    When you combine services into a single project, or combine in a project that is not a service layer, you run the risk of code leakage. A developer will eventually create a class that supports multiple services which starts to bind the services together in what initially is innocuous but slowly evolves into something more difficult to disentangle. Separate projects allows the framework to guarantee the absolute separatation of concern that ultimately leads to cleaner more supportable code.

    Projects can be viewed as nothing more than folders which enforce isolation. Anytime our architecture dictate a separate area of concern, that area should be a separate project with clear interfaces and boundaries.

  14. m_ means member_, so basically exactly what you mean, but now that stuff can start with _ instead of needing to start with a letter it's shortened to that.

  15. Models should be Model as each thing inside it is a Model. A Little like database tables. While logically that should apply to Services, Controllers etc, I generally pluralize them. In writing this I just realized I don't know why.

Leave a Reply

© 2023 53GB