Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Epic] Proposed Everyday C# TOC #34829

Open
BillWagner opened this issue Mar 30, 2023 · 9 comments
Open

[Epic] Proposed Everyday C# TOC #34829

BillWagner opened this issue Mar 30, 2023 · 9 comments
Labels
discussion Indicates issues that are being discussed Pri2

Comments

@BillWagner
Copy link
Member

BillWagner commented Mar 30, 2023

The following is an outline of the Everyday C# curriculum. It is not a complete syllabus. It has enough of an abstract for each section to begin writing that section.

  1. Intro / hello world: This section ensures that the reader has the correct tools installed, and can build and run applications locally. This section will use zone pivots to make it easier for readers on different operating systems. We'll gently Visual Studio on both PC and Mac, and VS Code on Linux. If developers prefer VS Code, they can use that pivot.
  • Objective: The developer has installed necessary tools, built their first local application, and explored some C# syntax.
  1. Algorithms: This section focuses on the elements of the C# language that developers use when they write the implementation of any method, local function, or property / indexer accessor. This section is the most changed by updating the "inner loop" coding tasks to use newer features. The techniques covered, and the samples will focus on using the latest features to write the most concise, readable code.
  • Objective: The developer feels comfortable writing code that implements their algorithms. It may not be the most performant, but is readable, and generally correct.
    The modules include:
    1. string type, and string interpolation.
    2. Numeric types, with a focus on int, and double.
    3. Working with collections, ranges and indexes. The samples will use Arrays , List<T>, and Dictionary<K, V>. Arrays will be limited to single-dimensional arrays. This module will include using index and range types to access elements and slices of collections. This will include loops to enumerate sequences (foreach, while, for and do - while).
    4. Imperative branching (if, else, switch)
    5. Query expressions and LINQ. Cover query syntax, fluent syntax, enumerating and transforming sequences. Lambda expressions are introduced here.
    6. lambda expressions for callbacks and events: Introduce the concept of callbacks, raising events, and the syntax behind those concepts. Lambdas were introduced with LINQ. This module will expand on those uses.
    7. Pattern matching. Introduce pattern matching as a way to write expression- based logic over imperative branching. This won't exhaustively cover all patterns, but instead provide several examples for type checking, property checking, and list patterns.
    8. async methods, awaiting method calls. This is an introduction to these features: Adding async on a method declaration, ensuring the return type is Task , Task<T>, and using await whenever calling an async method. In addition, introduce async enumerables to enumerate asynchronous data sources.
  • While not called out, samples will prefer the following features over alternatives:
    • top level statements and implicit usings
    • target-typed new
    • default is preferred over default(type) or null / 0 .
    • using statements over using blocks.
    • using directive without { }
      -auto-implemented properties, with initializers
    • ?., ??= and is not null for null safety.
    • with expressions, discards, and deconstruction
    • local functions
  • Not every idiom is covered in detail. For the "everyday C#" section, the most common scenarios are covered. There will be links to more in depth coverage of those areas. Second, some idioms aren't covered in everyday C# section at all. Some of those are techniques that aren't use in the most common scenarios. Others are techniques that were more common in earlier versions of C#.
  1. Program structure and types: As programs grow, all the techniques that organize code become important: assemblies, namespaces, types (classes, structs, interfaces, records), and generics.
  • Objective: The developer feels more comfortable working in a larger codebase, understands OO concepts, and can express more larger scale designs in C#. Modules include:
    1. Organizing programs: 34836 Explain the rationale to organize code as your program or library grows. Introduce the concepts to organize data and code into conceptual and physical packages.
    2. Defining types: One article to explain why C# programs are organized around creating types that map to concepts. This will introduce the concepts of reference types and value types.
    3. Tuples and records: These are the simplest data structures. Introduce them next. This won't cover every feature of records (namely, adding methods and behavior won't be covered).
    4. Structs: Slightly more complicated than records, so introduce them here.
    5. Classes: Add classes, and tie together the concepts of tuples, record, record struct and struct. Propose guidelines for deciding when to use which.
    6. Interfaces: Explain interfaces as a mechanism to build common contracts among distinct types. This doesn't cover more advanced features such as interface members.
    7. Commonalities: As new features have been added, the differences between classes, structs, and the record types have become fewer. That means choosing between them becomes more a matter of "making a right decision" than "making the right decision". Emphasize the commonality and the overlap so readers can make a reasonable decision.
    8. Generics: The reader will have seen the basics of generics in the examples using List<T> and Dictionary<K, V>. In this unit, add more of scenarios where developers will use and create generic methods and types.
    9. namespaces: The reader will have seen some namespaces in earlier content. Here, explain how you can organize your code using namespaces.
    10. Encapsulation, composition, Polymorphism: Finish with an introduction to these OO concepts.
  1. Resilient code: #34831 This unit introduces techniques to create code that's resilient when errors occur. The syntax for throwing and catching exceptions are covered, as are techniques to avoid corrupt data or results due to how exceptions are handled.
  • Objective: The developer can follow the general design guidelines for throwing exceptions, using finally clauses, and catching exceptions when recovery is possible.The following topics are covered:
    1. throwing exceptions: How to indicate failures using exceptions.
    2. catching exceptions: How to declare and use catch clauses when an exception can be handled.
    3. avoiding corrupt data : Finally clauses for memory cleanup, and code structure to minimize data corruption when exceptions occur.
  1. Coding style: This article will provide a basic set of coding guidelines. It won't be a complete set of guidelines and will focus on common techniques to write correct code. This will cover some of the most common naming conventions for types, fields, properties, and methods. It will stress guidelines for correctness (preferring braces for if / else in all cases). It will try and avoid more opinionated standards such as when to use var.
  • Objective: The developer can write code that generally conforms to the most common guidelines. Customers can point to these guidelines as a reasonable starting point for their own standards.
  1. XML documentation: ##34830 The final article provides a first example of using XML comments to generate documentation. It will link to the language reference section for a more complete treatment.
  • Objective: The developer can annotate their code with reasonable starting documentation comments .
    After finishing the content in this section, a developer should be reasonably prepared for an entry level coding position.
@dotnet-bot dotnet-bot added the ⌚ Not Triaged Not triaged label Mar 30, 2023
@BillWagner BillWagner added discussion Indicates issues that are being discussed and removed ⌚ Not Triaged Not triaged Pri3 labels Mar 30, 2023
@BillWagner
Copy link
Member Author

Areas outside of scope

The everyday C# section excludes many C# elements and techniques in order to focus on the most common techniques. This list explains why many areas of the language aren't covered in this section. (They are covered elsewhere in the C# guide.) The everyday C# section will link to the details on these sections for readers that want more depth on those techniques.

  • Techniques with improved alternatives: As C# grows, there are multiple code constructs for the same results. Rather than explain all alternatives, the everyday C# section will generally exclude the following.
    • Anonymous types: Developers should prefer tuples.
    • Imperative null-checks: In today's world, use !!, ?., ??=, and is null for as many as possible. All the everyday C# samples will have NRT enabled. Using if branches on null checks will be avoided.
    • Non-generic collections.
    • Defining delegate types, new delegate object won't be used. Instead, assign lambda expressions to Func or Action types.
    • Defining methods specifically for delegates. We may assign a delegate to a method group, but won't encourage creating a method for use in a delegate.
    • as, casts: the pattern matching is expression is a better solution.
    • static void Main(). We want developers to see the new top-level statements feature in more tutorials. The equivalent syntax will be explained because of the history, abundance of code already using the traditional entry point, and some scenarios that require a user-declared entrypoint.
  • Features that aren't in common scenarios: These features aren't used in the common scenarios that beginners will encounter.
    • default interface members
    • static abstract interface methods
    • pass-by-reference and pass-by-value, ref returns: These are less common for most scenarios.
    • ref struct, in arguments, readonly ref: Fundamentals will consume them, but without explanation on the nuances of pass by reference, and readonly references.
    • stackalloc, unsafe, fixed. These aren't used in many common scenarios.
    • dynamic
    • async techniques other than Task, async and await. This includes adding ConfigureAwait to async calls.
    • lock: Fundamentals will avoid parallelism.
    • volatile.
    • Partial methods and classes: Not as useful for core scenarios.
    • nint, nuint: These are specialized for native scenarios.
    • goto, continue, break (except in switch statements): These are less common, and can be confusing for beginners.
    • operator overloading: The everyday C# section will consume overloaded operators, but won't define them.
    • multi-targeting (.NET standard, etc)
    • Native interop: These aren't common scenarios

@kennethversaw
Copy link

Where do we find this curriculum at? Is this something you are working on or is it available now?

@BillWagner
Copy link
Member Author

Hi @kennethversaw

It's not available yet. This is the proposed table of contents for a major update to the C# Guide that I'll be making over the next several months.

I published this issue to get feedback on the proposed topics.

  • Is there anything to add?
  • Is there anything to remove?

@BillWagner BillWagner added Pri2 and removed Pri3 labels Apr 18, 2023
@jnm2
Copy link
Contributor

jnm2 commented Apr 20, 2023

What about a focus on testable coding? Functional-core-imperative-shell is a great structure. Another structure is the use of interfaces to enable lightweight tests which intercept things like I/O.

@BillWagner
Copy link
Member Author

I got a question offline .

Topics like dependency injection or config handling. Are they out of scope because they aren't language features?

They won't be explicitly covered here because they aren't langauge features. However, the samples will use them because they are common practices in current application development. Where needed, the articles using them will link to articles that explain those library concepts.

@jnm2
Copy link
Contributor

jnm2 commented Apr 20, 2023

Also, what about the required keyword or raw string literals?

@BillWagner
Copy link
Member Author

Also, what about the required keyword or raw string literals?

Yes to both.

@BillWagner
Copy link
Member Author

What about a focus on testable coding? Functional-core-imperative-shell is a great structure. Another structure is the use of interfaces to enable lightweight tests which intercept things like I/O.

Good idea. I added a draft issue in this project to track this.

@AhmedBaraa
Copy link

jpo ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Indicates issues that are being discussed Pri2
Projects
Status: 🆕 New
Development

No branches or pull requests

5 participants