A collection of independent or loosely-coupled packages to enhance the syntax of C# in a minimal way.
The C# Language Syntactic Sugar suite was created out of my frustration working with C#. The language and its Class Library have not evolved fast enough to address the inconsistencies, performance traps, unintuitiveness and lacking accommodation of common use-cases despite it is very much inline with the language's tradition to accommodate such use-cases. It still lacks some batteries for a "batteries included" language, even long after the inclusion in the BCL of types that serve a very niche use case such as the Version type that parses version strings in the major.minor[.build[.revision]]
syntax and also programmatically implements IComparable<T>
and IEquatable<T>
.
Even when these concerns are addressed, they only come to the latest versions of the language and Class Library. Working in a bleeding-edge .NET environment is a luxury for many developers.
Our good friends such as language-ext, csharp-extensions and CSharpFunctionalExtensions made great efforts to address such concerns but one issue remains. Like many other language extension packages, their monolithic structure creates a high risk of conflicting with existing extension methods in your own projects once you using
their namespaces.
CLSS set out to go in a different direction.
CLSS suite embraces the Unix philosophy. CLSS tried not to be one monolothic package but rather an umbrella for multiple packages. Each package is laser-focused on providing one functionality and can be installed (mostly) independently of other packages. Only install what you want and what is compatible with your current project, and no more.
There are several irregulaties in the .NET Standard Library.
Why is there a GetOrAdd
method for ConcurrentDictionary
but not for other Dictionary types?
Why is there a ForEach
method for List<T>
but not for other iteratable collections?
Why does Enum.Parse
allow non-Enum value types in its type parameter?
If you ever felt like these irregularities should not have existed to provide better consistency, CLSS suite offers a solution for you. It fills in the gaps left by the Base Class Library. Its XML comments do the best to resemble ones that ship with classes and methods in the BCL. Its implementations try to follow the .NET reference source as closely as possible. CLSS suite is built to make the BCL feel complete, to take the "batteries included" philosophy one step further. To add more batteries, so to speak.
Inkeeping with the intent to feel like a natural part of the language and its Class Library, CLSS will be averse to being revolutionary such as language-ext. CLSS packages may lean toward the syntax of functional programming, but will commit to the familiarity of the C# syntax. No monad or endofunctor here. Just functional programming the way you can still recognize as C#.
A secondary goal of CLSS suite is to polyfill for older language versions and .NET versions. Some of the features from new .NET versions that CLSS can polyfill are: LINQ MaxBy
/MinBy
, shared Random
instance and array filling.
CLSS packages multi-target .NET Standard 2.0 and - wherever possible - as low as .NET Standard 1.0. Learn how compatible these standards are here.
You can find and install every CLSS packages under the 'CLSS' tag on the NuGet Gallery.
To start using CLSS packages after installing, add this line to the top of your C# source file:
using CLSS;
Package-specific issues should be submitted to their respective repositories. If you have an idea that you think should make it into the shared CLSS
namespace, submit an issue to this repository.
Below is the list of packages contained in the CLSS suite so far:
CLSS.Constants.DefaultRandom
(Source): A default-constructed instance of the System.Random class.CLSS.Constants.NoOp
(Source): A collection of statically-defined No-op methods used in place of anonymous no-ops to save memory allocations.CLSS.ExtensionMethods.CommonMathOps
(Source): A collection of common math operations in a functional syntax.CLSS.ExtensionMethods.IComparable.InRange
(Source): An extension method to check whether the source value is within a range.CLSS.ExtensionMethods.IDictionary.GetOrAdd
(Source): An extension method to provide GetOrAdd as found in ConcurrentDictionary to every IDictionary type.CLSS.ExtensionMethods.IDictionary.MoveKey
(Source): An extension method to move the value of a dictionary's key to another key.CLSS.ExtensionMethods.IEnumerable.ForEach
(Source): An extension method to provide ForEach as found in List to every IEnumerable type.CLSS.ExtensionMethods.IEnumerable.MinMaxBy
(Source): An extension method to provide MinBy and MaxBy as found in .NET 6 to projects running on an earlier runtime version.CLSS.ExtensionMethods.IList.FillBy
(Source): An extension method to fill all indices of an IList with a default value.CLSS.ExtensionMethods.IList.FirstLastIndex
(Source): An extension method to find the first or last index of an IList element matching a condition.CLSS.ExtensionMethods.IList.SwapIndices
(Source): An extension method to swap the values at 2 different indices in an IList.CLSS.ExtensionMethods.Object.As
(Source): An extension method to cast reference types in a functional-style syntax.CLSS.ExtensionMethods.Object.Is
(Source): An extension method to check reference types in a functional-style syntax.CLSS.ExtensionMethods.Pipe
(Source): An extension method to replicate the pipe syntax (take the source value and feed it as an argument to a method).CLSS.ExtensionMethods.String.AsEnum
(Source): An extension method to provide a type-safe and functional style way to convert strings to enums.CLSS.Types.MemoizedFunc
(Source): A class that encapsulates a function to automatically memoize its results.CLSS.Types.Reference
(Source): A class that encapsulates a single value with the primary intention of making value types referenceable.CLSS.Types.SortedAction
(Source): A delegate-like type that allows executions by key order.CLSS.Types.ValueRange
(Source): A type-safe, serializable generic struct type tailored to semantically represent a range of comparable values.
CLSS.ExtensionMethods.IList.ExclusiveSample
(Source): An extension method to randomly selection a number of non-repeating elements out of an IList using Donald Knuth's Algorithm S (Selection sampling technique).CLSS.ExtensionMethods.IList.GetRandom
(Source): An extension method to select a random element from a list.CLSS.ExtensionMethods.IList.GetWeightedRandom
(Source): An extension method to select a weighted random element from a list.CLSS.ExtensionMethods.IList.Shuffle
(Source): An extension method to shuffle an IList in place using the Fisher-Yates algorithm.CLSS.Types.WeightedSampler
(Source): A struct type that wraps around a list collection to select a weighted random element from it efficiently.
CLSS.ExtensionMethods.IComparable.ClampToRange
(Source): An extension method to clamp the source value into a range.CLSS.ExtensionMethods.IDictionary.SwapKeys
(Source): An extension method to swap the values at 2 different keys in an IDictionary.CLSS.ExtensionMethods.IEnumerator.LoopNext
(Source): An extension method to infinitely advance an enumerator in a loop.CLSS.ExtensionMethods.Object.ToStringFormattedBy
(Source): An extension method to transform one or several objects into string form following a particular format.
CLSS.Constants.ValueEquivalentStrings
(Source): A global cache of default string representations of values of value types.CLSS.ExtensionMethods.IEnumerable.Looping
(Source): An extension method create an enumerable that infinitely loops over a collection.CLSS.ExtensionMethods.IList.GetLoopingElementAt
(Source): An extension method to cyclically convert any integer number into a valid index to get an element from a list.
CLSS.ExtensionMethods.Reference.Action.Once
(Source): An extension method to register a listener to a delegate that will only execute once.CLSS.Types.EventLatch
(Source): A synchronisation aid object for single-threaded context.
CLSS.ExtensionMethods.IDictionary.RemoveAndProcess
(Source): An extension method that combines the removal of a key from an IDictionary and post-removal processing of that key's associated value into one method call.CLSS.ExtensionMethods.IList.RemoveAndProcess
(Source): An extension method that combines the removal of an element from an IList and post-removal processing of that element into one method call.CLSS.Types.AgnosticObjectPool
(Source): A domain-agnostic object pool that only handles pooling logic and lets you customize object creation and availability checking logic.
CLSS.Constants.CollectionPool
(Source): A collection of statically-defined pools of Base Class Library's built-in collection types.