A utility library for transforming values using delegates in C#.
DelegateTransform is a utility library that provides methods for transforming values using various delegate types in C#. It offers a clean and efficient way to apply transformations using ActionRef, Func, and FuncRef delegates, making your code more readable and functional.
Important: All With methods return a new transformed value - they never mutate the original input. This provides functional programming semantics even when using reference-based delegates.
- ActionRef Transformations: Modify copies of values by reference using action delegates
- Func Transformations: Transform values using function delegates
- FuncRef Transformations: Transform values by reference using function delegates that return values
- Copy-on-Transform: Original values are never mutated
- Generic Implementation: Works with any value or reference type
- .NET 10.0, 9.0, 8.0, 7.0, 6.0
- .NET Standard 2.1
Install-Package ktsu.DelegateTransformdotnet add package ktsu.DelegateTransform<PackageReferenceInclude="ktsu.DelegateTransform"Version="x.y.z" />The With method can be used with an ActionRef<T> delegate to apply a transformation by reference and return the result:
usingktsu.DelegateTransform;intinput=5;intresult=DelegateTransform.With(input,(refintx)=>x*=2);// result is 10, input is still 5 (original unchanged)The With method can be used with a Func<T, T> delegate to transform the input value:
usingktsu.DelegateTransform;intinput=5;intresult=DelegateTransform.With(input, x =>x*2);// result is 10The With method can be used with a FuncRef<T> delegate to transform the input value by reference:
usingktsu.DelegateTransform;intinput=5;intresult=DelegateTransform.With(input,(refintx)=>x*x);// result is 25, input is still 5 (original unchanged)You can chain multiple transformations by nesting calls:
usingktsu.DelegateTransform;// Starting valuestringinput="example";// Chain of transformationsstringstep1=DelegateTransform.With(input, s =>s.ToUpper());// "EXAMPLE"stringstep2=DelegateTransform.With(step1, s =>s.Replace("EX","**"));// "**AMPLE"stringresult=DelegateTransform.With(step2, s =>s+" transformed");// "**AMPLE transformed"Console.WriteLine(result);// Outputs: **AMPLE transformedusingktsu.DelegateTransform;varperson=newPerson{Name="John",Age=30};// Transform using ActionRef (for reference types, the object is modified)PersonupdatedPerson=DelegateTransform.With(person,(refPersonp)=>{p.Name=p.Name.ToUpper();p.Age+=1;});Console.WriteLine($"{updatedPerson.Name}, {updatedPerson.Age}");// Outputs: JOHN, 31// Transform using Func to create a string descriptionstringdescription=DelegateTransform.With(person, p =>$"{p.Name} is {p.Age} years old");Console.WriteLine(description);// Outputs: JOHN is 31 years old// Custom delegate for actions on referencespublicdelegatevoidActionRef<T>(refTitem);// Custom delegate for functions on referencespublicdelegateTFuncRef<T>(refTitem);The main class providing transformation methods.
| Method | Parameters | Return Type | Description |
|---|---|---|---|
With<T> | T input, ActionRef<T> delegate | T | Creates a copy, applies the action by reference, returns the modified copy |
With<T> | T input, Func<T, T> delegate | T | Applies a function to the input and returns the result |
With<T> | T input, FuncRef<T> delegate | T | Passes input by reference to the function and returns the result |
All methods throw ArgumentNullException if the delegate is null.
The library follows a functional programming pattern where the original input is never mutated:
publicstaticTWith<T>(Tinput,ActionRef<T>@delegate){Ensure.NotNull(@delegate);Toutput=input;// Creates a copy@delegate(refoutput);returnoutput;}This ensures predictable behavior and prevents side effects on the original values.
For value types (structs), a copy is made before transformation. For large structs where you want to avoid copying, consider using the FuncRef<T> overload which passes by reference and returns the modified value.
For reference types (classes), the "copy" is actually a copy of the reference, so the underlying object can be modified. If you need true immutability for reference types, create a new instance within your delegate.
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please make sure to update tests as appropriate and adhere to the existing coding style.
This project is licensed under the MIT License - see the LICENSE.md file for details.