
Study the meta principles behind clean code in C#, including dry, kiss, yagni, separation of concerns, command query separation, least astonishment, and information hiding.
Master the dry principle to avoid duplication, replace magic values with meaningful constants, refactor duplicated logic into common methods, and apply the open-closed principle to replace switch cases.
Apply the kiss principle to keep software simple by reducing accidental complexity through decomposition and SOLID design, favoring composition over inheritance and avoiding premature optimization.
emphasizes the Yagni principle to avoid overengineering by implementing only what is needed now, weighing future costs such as delay and carry.
Apply separation of concerns to build modular systems by isolating ui, business logic, presentation, and database; avoid leaking abstractions and keep domain logic persistence agnostic for easier maintenance.
Explore the command query separation principle by Bertrand Meyer, ensuring methods are either commands or queries—not both—so APIs remain honest and easy to reason about.
Master the principle of least astonishment and its role in safe API design, avoiding temporal coupling, and ensuring predictable, expectation-driven behavior for users and clients.
Learn how encapsulation and information hiding protect invariants by exposing safe interfaces and hiding internal state. Use constructors, properties, and query methods to build robust, foolproof APIs.
Learn general principles of naming in c# and dotnet, emphasizing readability, maintainability, and refactoring with modern tools for renaming variables and dependent declarations, as well as extracting classes and interfaces.
Apply general naming principles to write readable C# code with intention revealing names, using English terms and domain terms, and follow dotnet conventions for classes (nouns) and functions (verbs).
Master the art of writing clean code in C# by exploring clean functions, clean variable declarations, avoiding magic numbers, stringly typing, and refactoring techniques like extract method and guard clauses.
Discover why declaring variables at the top of methods can hinder readability and trigger context switching, and learn to place declarations near usage for cleaner code in C Sharp.
Identify magic numbers as a code smell and replace them with well named constants or an enumeration to improve readability and reduce complex conditional logic.
Explore the stringly typed code smell, learn why using string literals like red, yellow, green is error prone, and refactor into enums or strong abstractions to ensure type safety.
Explore when to implement a member as a property or a method, weighing parameter count, overloads, and optional parameters, and emphasize properties are simple, cohesive, and API friendly.
Limit function parameters to three and extract extras into a parameter object or class. Refactor into two methods or use a date range structure to improve readability and single responsibility.
Explore extract method refactoring to replace a search with focused methods like get closest and calculate distance, convert the for loop to for each, and isolate pure logic for testability.
Explore determining overlapping ranges using a begin and end properties structure, noting non-inclusive ends, and refactor complex overlap logic by validating non-overlap cases for simpler, reliable comparisons.
Explore the sequence of arguments in if statements and methods, debunk yoda notation, and show how named parameters improve readability in c# unit tests and assertions.
Explore guard clauses and early returns to improve readability and reduce nesting, and evaluate single versus multiple return statements in clean code. Assess how null checks influence clean code.
Refactor complex conditionals by replacing them with ternary operators or switch statements to improve readability. Extract descriptive intermediary variables and well-named methods to centralize validation logic and boost maintainability.
Explore handling output parameters and the try pass pattern, refactoring to a dedicated class, and using a result monad or tuples to enable clean, error-aware pipelines in C-sharp seven.
Evaluate when to use comments and when to avoid them, refactor to self-explanatory methods, and use targeted comments to reveal concepts like the Eratosthenes sieve in prime generation.
Learn to improve code readability in C# by using affirmative boolean predicates instead of double negatives, and name booleans clearly.
Refactor code smell by turning magic numbers into constants, avoiding top-of-method declarations, and favor strong types over generic strings; use guard clauses, reduce long methods, and group parameters into classes.
Explore architectural design smells, including primitive obsession and temporal coupling, and apply the law of Demeter while refactoring switch statements with template method, strategy, and state patterns.
Transform primitive string representations into a dedicated zip code class to encapsulate validation and business rules, avoiding design smells and enabling casting and cleaner APIs.
Explore Demeter, a guideline for loose coupling. See how exposing a wallet breaks encapsulation in a paper boy scenario, and fix it by delegating payment to the customer.
Explore the strategy pattern, a behavioral design pattern that selects an algorithm at run time, decouples clients from algorithms, and uses dependency injection to delegate behavior through an interface.
Examine primitive obsession, showing why strings for zip codes create clutter and costs. Navigate demeter coupling, temporal coupling, and refactor switch statements with template method, dictionary, strategy, and state patterns.
Discover functional programming as a paradigm that treats computation as mathematical functions, avoids state changes, and relies on declarative expressions and independent, testable code.
Explore how objects drive object-oriented programming in C#, and how functions serve as first class citizens, guided by best practices, SOLID principles, and functional patterns.
Explore why learning functional programming matters, even from PHP ideas, to reduce code, enable composable, reusable components, and improve safety, immutability, no shared state, and concurrency safety.
Explore immutability as a core functional programming concept, show how returning new instances instead of mutating state improves readability and safety for concurrent access, and reduces temporal coupling.
Compare structures and classes, structures copy by value, classes by reference, and spot the risks of mutable structures. See a point struct that returns new instances to achieve true immutability.
Explore how pipelining passes the output of one function to the next to streamline data flow in C# via method chaining.
Explore extending IDisposable types to enable functional composition with using blocks, wrapping stream readers and a data parser to parse CSV data and map types while avoiding nulls.
Learn how general extensions in C# enable fluent call chains, type conversion, and predicate-driven processing to keep code readable and functional, from date time to device formats.
Master the builder pattern for immutable objects and fluent APIs, demonstrated with a person class and a testable phone service built via unit tests with mocks and a dependency builder.
Explore why exceptions clash with functional programming and learn to replace out parameters with a result class that encodes success, error, and optional value, enabling safe pipelining.
Explore how to implement pipelining in C# through method chaining with a result class and extension methods, enabling clean, flat control flow for success and failure paths.
Explore functional programming techniques in C# to reduce code, improve immutability, and build composable, testable components; learn fluent APIs, extension patterns, and error handling with the result monad.
Explore common antipatterns and refactorings in dependency injection, including constructor over injection, ambient context, and service locator, and address cyclic dependencies with the factory pattern.
Identify and fix the control freak anti-pattern by moving payment method creation from the view model to a dedicated factory, enabling dependency injection, runtime selection, and abstract factory use.
Expose all dependencies in the public api to enforce the contract and prevent hidden preconditions, using the constructor so callers provide required instances and the compiler validates them.
Temporal coupling creates hidden interconnections in an API that require a specific call order. Enforce constructor injection, such as requiring a Uri, to eliminate this coupling and prevent invalid states.
Use ambient context to provide access to utility dependencies like I progress event aggregator and I prompt creator, enabling unit testing and reducing constructor complexity for hundreds of view models.
Explore how a facade service encapsulates accounts receivable, irate exchange, and a user context, reinforcing the single responsibility principle and consolidating logic with an order collector interface.
Identify and break cyclic dependencies by inverting the cycle with events or callbacks, or introducing interfaces and an abstract factory to decouple components and avoid resolution errors.
Contrast control freak patterns with dependency injection and avoid the service locator anti-pattern. Note risks like many dependencies and temporal coupling, and embrace inversion of control for cleaner architecture.
Examine how singletons and static classes introduce global dependencies that hinder unit testing, and how explicit initialization and constructor injection can improve testability and design.
Identify primitive obsession and model a four-part record (id, currency, pair rate, stamp) with readonly properties, then implement a file manager, persister, and quotation service with accompanying tests.
Explore the rule of a single logical assertion in unit tests, clarifying when multiple assertions test the same aspect, with examples from a money class and currency properties.
Learn to write trustworthy, readable, and maintainable unit tests by avoiding control flow and duplication, avoiding multiple mocks, and avoiding ordered tests and over specification, with guidance on cleanup.
Explore clean code practices in C#, showing how singletons, static classes, and single interface implementation hinder tests, and how to test one logical unit per test with daily best practices.
Explain what tdd is and why we need it, cover red green refactor and the three laws, and show tdd in a tic tac toe game with roman numerals.
Drive production code with tests by writing unit tests first, shaping a modular, testable design, and achieving about 70% test coverage while reducing production bugs by 40–80%.
Master the red green refactor cycle of test driven development by writing a unit test, building production code with Resharper to pass, and refactoring, repeating until the feature is complete.
Master the three laws of test driven development by writing a failing test first. Keep tests minimal and avoid excessive production code, enabling rapid cycles and near 100% code coverage.
Learn how continuous testing automates running related tests on code changes, leveraging tools like NCrunch and its live unit testing to speed feedback and support TDD.
Practice test-driven development by building a 3x3 tic tac toe game in c#, using a board, a moves counter, and a state enum for cross and zero, with tests.
Conclude by summarizing TDD principles, red green refactor, and three laws, with roman numerals conversion and tic tac toe as examples, showing continuous testing and client-driven API design.
Join the mailing list for discounts on paid courses and access links to other video courses, while leaving reviews and supporting the creator on Patreon.
Learn how to design and implement types in C# so that the other developers won't hate you when using one of the types developed by you. It means you are going to learn how to write code of the high quality: readable, understandable and reliable.
Improve your knowledge in object-oriented programming in the context of clean coding and building types of high quality.
Foundations of building object-oriented infrastructures
Despite the fact that C# is a very rich on features language, it's very common to see poorly designed and implemented types in a real world. In fact, C# is one of the richest on features language among object-oriented languages in the world nowadays. But with great power comes great responsibility. It's challenging to use all those features in a right way.
You probably have already heard the following well-known statement: most code sucks. Well, this course is all about how to produce code which doesn't suck.
Owning skills of producing a well-designed and well-implemented types is the prerequisite for the other developers to treat you as a real professional.
Content and Overview
This course is aimed at all the C# developers, from beginners to seniors. Topics which are covered in the course are relevant for all kinds of C# developers since all developers design and implement APIs. The topics complexity is very different. There are plenty of very simple topics, and at the same time, there are topics which require from you a solid C# background. There are plenty of code examples throughout this course, so you will learn both theoretical and practical material.
The course covers the following topics:
The list is far from being complete. The course covers a great number of topics. Enroll and start Mastering the Art of Writing Clean Code in C#!
------------------------------------------------------------
Keywords related to the course: