Coder Social home page Coder Social logo

in-op / systemextensions Goto Github PK

View Code? Open in Web Editor NEW
2.0 2.0 0.0 76 KB

A class library of extension methods and interfaces that fill holes in the basic System libraries

C# 100.00%
extension-methods system csharp random arrays deepcopy deep-clone deepclone extensions

systemextensions's Introduction

Summary

A class library of interfaces and extension-methods that round out the basic System libraries to fill unnecessary holes

API

Jagged Array

The JaggedArray class was created to easily initialize jagged arrays (arrays of arrays) of multiple dimensions (not to be confused with multidimensional arrays). Jagged arrays are generally faster to access than multidimensional arrays, but initializing jagged arrays is a cumbersome process in the normal language compared with multidimensional arrays.

This class contains one overloaded method, JaggedArray.Create. All overloads allow you to generate jagged arrays with specified lengths for arrays in each dimension.

T[][][] JaggedArray.Create<T>(
    int length1D,
    int length2D,
    int length3D)

Generating arrays like this initializes each element to the default value. An initial value can also be specified explicitly, either directly as an argument (only if it's a value type):

T[][][] JaggedArray.Create<T>(
    int length1D,
    int length2D,
    int length3D
    T val)
    where T : struct

or indirectly as the return value of a func argument:

T[][][] JaggedArray.Create<T>(
    int length1D,
    int length2D,
    int length3D
    Func<T> func)

This allows the flexibility to construct objects, set random numbers, or do whatever you'd like in your array elements during initialization. Jagged arrays between one and five dimensions, T[] to T[][][][][], are currently supported. Note that all arrays in each dimension must be the same length. This means you can't have a jagged array like this:

int[][] array = new int[3][] 
{
    new int[1] { 42 },
    new int[3] { 100, 101, 102 },
    new int[2] { 56, -15 }
}

where the lengths of inner arrays differ. Sometimes this is useful, such as when storing large amounts of data. Support is given for specifying individual lengths for whatever is the final dimension of the array:

T[][][] JaggedArray.Create<T>(
    int length1D,
    int length2D,
    int[] lengths3D)

If you require jagged arrays with varying lengths in multiple dimensions, the content is probably complex enough to warrant manual initialization.

Copying

The SystemExtensions.Copying namespace was created to facilitate the implementation of creating deep copies of your custom types. Deep copying is the creation of an instance whose fields contain the exact same values as some original instance, but the two instances share no mutable state. This can be useful in a number of situations, including multithreaded applications. However, implementing deep copy methods can be confusing and painful, depending on the complexity of the objects you copy. Deep copying is easy when the state is perfectly immutable, but tricky when you have objects within objects and both have mutable state.

The Copying namespace supports DeepCopy() extension methods for the following types:

  • T[]
  • Dictionary<TKey, TValue>
  • HashSet<T>
  • List<T>

It also defines an interface for producing deep copies for your custom types:

public interface ICopyable<T>
{
    T DeepCopy()
}

You can implement it like this:

class Point : ICopyable<Point>
{
    public int x, y;
    public Point(int x, int y) { this.x = x; this.y = y; }
    public Point DeepCopy() { return new Point(x, y); }
}

Custom types that implement the ICopyable interface can interop with any of the supported types' DeepCopy() extension methods. If the supported type's generic type is your custom type, it will safely execute DeepCopy(). For example:

static void main(string[] args)
{
    List<Point> list = new List<Point>(3)
    {
        new Point(1, 2),
        new Point(10, 42),
        new Point(-3, 6)
    }
    
    List<Point> copy = list.DeepCopy();
}

This code compiles and does not throw any errors. As long as your type implements the ICopyable<T> interface you are safe to deep copy any of the supported generic types which use your type as generic type parameters.

It is important to recognize where your types are mutable and immutable, and deep copy appropriately. All the built-in value types (bool, int, etc.) are safe to simply assign directly to the copy. If you have objects with other objects in their fields, simply define deep copy methods for the inner objects. Then when defining DeepCopy() for the containing type, simply assign the copy's field to: originalObject.DeepCopy(). This makes deep copying as simple as walking through the fields of your object and assigning data either directly from the original, when the type is immutable, or directly from a DeepCopy() invocation, when the type is mutable.

All supported types can also contain other supported types as generic type parameters. For example, instances of type List<HashSet<Point[]>> will execute DeepCopy() correctly (please never define anything as that type).

If, however, you make a List<MyTypeThatDoesntImplementDeepCopy> and call the extention method DeepCopy() on it, it will throw a NotImplementedException at runtime and warn you that your type does not implement ICopyable.

Random

The Random namespace provides extension methods for retrieving random items out of collections, for creating a random Int64 long value from a Random instance, and generating thread-safe Random instances.

T RandomItem<T>(this List<T> list, System.Random rng)

The principle method for retrieving a random item from the collection. All collections supporting this extension method:

  • T[]
  • Dictionary<TKey, TValue>
  • HashSet<T>
  • List<T>
long NextInt64(this System.Random rng)

Returns a random Int64 long value from the calling Random instance.

Random ThreadLocalRandom.NewRandom()

Returns a new Random instance whos seed is derived from a locked, global Random instance, rather than time. This us useful when you need to generate thread-local Random instances, and are running into the problem where they all have similar seed values.

systemextensions's People

Contributors

in-op avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.