Namespaces to organize types

Namespaces are heavily used in C# programming in two ways. First, .NET uses namespaces to organize its many classes

namespace SqlServerLibrary
namespace SqlServerLibrary.LanguageExtensions
                            

Records

A Record is a class that provides special syntax and behavior for working with data models. For information about classes, see Classes.

See How records differ from classes, we will get into records later.

Classes

A type that is defined as a class is a reference type. At run time, when you declare a variable of a reference type, the variable contains the value null until you explicitly create an instance of the class by using the new operator, or assign it an object of a compatible type that may have been created elsewhere.

public class Customer
                                {
                                    /// <summary>
                                    /// Primary key
                                    /// </summary>
                                    public int Id { getset; }
                                    /// <summary>
                                    /// Customer first name
                                    /// </summary>
                                    public string? FirstName { getset; }
                                    /// <summary>
                                    /// Used to teach [is null]
                                    /// </summary>
                                    public int? Value { getset; }
                                }

Interfaces - define behavior for multiple types

An interface contains definitions for a group of related functionalities that a non-abstract class or a struct must implement. An interface may define static methods, which must have an implementation. Beginning with C# 8.0, an interface may define a default implementationfor members. An interface may not declare instance data such as fields, auto-implemented properties, or property-like events.


                            public interface IPerson
                            {
                                int Id { getset; }
                            }

Generic classes and methods

Generics introduces the concept of type parameters to .NET, which make it possible to design classes and methods that defer the specification of one or more types until the class or method is declared and instantiated by client code. For example, by using a generic type parameter T, you can write a single class that other client code can use without incurring the cost or risk of runtime casts or boxing operations

public static class GenericExtensions
                                {
                                    public static bool IsNull<T>(this T senderInstancewhere T : new() => 
                                        senderInstance is null;
                                    public static bool IsNotNull<T>(this T senderInstancewhere T : new() => 
                                        !senderInstance.IsNull();
                                    public static bool Between<T>(this IComparable<T> sender, T minimumValue, T maximumValue) => 
                                        sender.CompareTo(minimumValue) >= 0 && sender.CompareTo(maximumValue) <= 0;                               
                                }

Generic classes and methods combine reusability, type safety, and efficiency in a way that their non-generic counterparts cannot. Generics are most frequently used with collections and the methods that operate on them. The System.Collections.Generic namespace contains several generic-based collection classes. The non-generic collections, such as ArrayList are not recommended and are maintained for compatibility purposes. For more information, see Generics in .NET.

Generic Interfaces It is often useful to define interfaces either for generic collection classes, or for the generic classes that represent items in the collection. The preference for generic classes is to use generic interfaces, such as IComparable<T> rather than IComparable, in order to avoid boxing and unboxing operations on value types. The .NET class library defines several generic interfaces for use with the collection classes in the System.Collections.Generic namespace.

public interface IClassActions<T>
                                {
                                    T GetById(decimal id);
                                    T Update(T entity);
                                    T Add(T entity);
                                    T Delete(int id);
                                    int Commit();
                                    List<T> GetAll();
                                }

Throughout training generics will be used often.

See also