PowerCSharp.Extensions provides cross-platform extension methods for .NET developers that enhance productivity and simplify common programming tasks. This package contains over 100 extension methods organized into logical categories including strings, collections, LINQ, JSON, XML, objects, types, streams, and exception handling.
Note: ASP.NET Core specific extensions (Configuration, HTTP utilities, URI manipulation) are now available in the separate PowerCSharp.Extensions.AspNetCore package for cleaner dependency management.
Recent Improvements (v0.3.0):
- Package Separation: ASP.NET Core extensions moved to dedicated package
- Performance Optimization: Reduced memory allocations and improved execution speed
- Enhanced Documentation: Better API documentation with practical examples
- Improved Testing: Expanded unit test coverage for all extension methods
- Better Error Handling: More robust error handling and edge case coverage
- Fluent API: Chainable methods for expressive code
- Null Safety: Comprehensive null checking and handling
- Performance: Optimized implementations for common scenarios
- Consistency: Uniform naming and behavior patterns
- Extensibility: Easy to extend with custom methods
PowerCSharp.Extensions/
├── Collections/
│ ├── CollectionExtensions.cs
│ └── IListExtensions.cs
├── DateTimeExtensions.cs
├── EnumerableExtensions.cs
├── Json/
│ ├── JsonExtensions.cs
│ └── JsonElementExtensions.cs
├── Linq/
│ ├── DynamicExpressionExtensions.cs
│ └── IEnumerableExtensions.cs
├── Objects/
│ ├── ExceptionExtensions.cs
│ ├── GenericExtensions.cs
│ ├── HashExtensions.cs
│ └── ObjectExtensions.cs
├── Streams/
│ └── StreamExtensions.cs
├── Strings/
│ ├── EnumExtensions.cs
│ └── StringExtensions.cs
├── Types/
│ ├── GenericTypeExtensions.cs
│ └── TypeExtensions.cs
├── IO/
│ └── PathExtensions.cs
└── Xml/
└── XmlExtensions.cs
Moved to PowerCSharp.Extensions.AspNetCore:
- Configuration/ConfigurationExtensions.cs
- Net/UriExtensions.cs
- Http/HttpStatusCodeExtensions.cs
- Http/HttpRequestMessageExtensions.cs
- PowerCSharp.Core v0.3.0 - Shared interfaces and base functionality
- System.Linq.Dynamic.Core v1.7.2 - Dynamic LINQ expression parsing
- Ben.Demystifier v0.4.1 - Enhanced exception demystification
- System.Text.Json v10.0.8 - JSON processing
- .NET 8.0 - Latest features and optimizations
- .NET Standard 2.0 - Cross-platform compatibility
- Package Compatibility: Ensured all dependencies are compatible with .NET 8.0
- Dependency Updates: Updated to latest stable versions of all dependencies
- Build Improvements: Enhanced package generation with symbol packages
Enhanced date and time operations for common scenarios.
public static int GetAge(this DateTime birthDate)Purpose: Calculates age based on birth date.
Parameters:
birthDate: The birth date
Returns: Age in years
Examples:
DateTime birthDate = new DateTime(1990, 5, 15);
int age = birthDate.GetAge(); // Returns current age based on today's date
// In a user management system
public class User
{
public DateTime BirthDate { get; set; }
public int Age => BirthDate.GetAge();
public bool IsAdult => Age >= 18;
}public static bool IsWeekend(this DateTime date)Purpose: Checks if a date falls on a weekend.
Parameters:
date: The date to check
Returns: True if Saturday or Sunday, false otherwise
Examples:
DateTime today = DateTime.Now;
bool isWeekend = today.IsWeekend();
// In a scheduling system
public class TaskScheduler
{
public bool CanScheduleTask(DateTime date)
{
if (date.IsWeekend())
{
Console.WriteLine("Task cannot be scheduled on weekend");
return false;
}
return true;
}
}public static DateTime FirstDayOfMonth(this DateTime date)
public static DateTime LastDayOfMonth(this DateTime date)Purpose: Gets the first or last day of the month for a given date.
Examples:
DateTime today = DateTime.Now;
DateTime firstDay = today.FirstDayOfMonth();
DateTime lastDay = today.LastDayOfMonth();
// In a reporting system
public class MonthlyReportGenerator
{
public DateTime GetReportPeriod(DateTime date)
{
return new DateTime(date.Year, date.Month, 1);
}
public List<DailyData> GetMonthData(DateTime date)
{
DateTime start = date.FirstDayOfMonth();
DateTime end = date.LastDayOfMonth();
return GetDataBetweenDates(start, end);
}
}Powerful string manipulation and validation methods.
public static string ToTitleCase(this string input)Purpose: Converts a string to title case (first letter of each word capitalized).
Examples:
string text = "hello world";
string titleCase = text.ToTitleCase(); // "Hello World"
// In a data processing system
public class DataFormatter
{
public string FormatName(string firstName, string lastName)
{
return $"{firstName.ToTitleCase()} {lastName.ToTitleCase()}";
}
public string FormatAddress(string address)
{
return address.ToTitleCase();
}
}public static string ToCamelCase(this string input)Purpose: Converts a string to camelCase format.
Examples:
string text = "HelloWorld";
string camelCase = text.ToCamelCase(); // "helloWorld"
// In a code generation system
public class CodeGenerator
{
public string GeneratePropertyName(string fieldName)
{
return fieldName.ToCamelCase();
}
public string GenerateVariableName(string description)
{
return description.Replace(" ", "").ToCamelCase();
}
}public static bool IsValidUrl(this string input)Purpose: Validates if a string is a valid absolute HTTP or HTTPS URL.
Examples:
string url1 = "https://example.com";
bool isValid1 = url1.IsValidUrl(); // true
string url2 = "not-a-url";
bool isValid2 = url2.IsValidUrl(); // false
// In a validation system
public class InputValidator
{
public bool ValidateWebsite(string website)
{
return string.IsNullOrEmpty(website) || website.IsValidUrl();
}
public bool ValidateApiEndpoint(string endpoint)
{
return endpoint.IsValidUrl();
}
}public static bool IsNullOrWhiteSpace(this string input)Purpose: Checks if a string is null, empty, or contains only whitespace.
Examples:
string text = " ";
bool isEmpty = text.IsNullOrWhiteSpace(); // true
// In a validation system
public class RequiredFieldValidator
{
public bool ValidateField(string value)
{
return !value.IsNullOrWhiteSpace();
}
public string SanitizeInput(string input)
{
return input.IsNullOrWhiteSpace() ? string.Empty : input.Trim();
}
}Enhanced collection operations for better data manipulation.
public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)Purpose: Checks if a collection is null or empty.
Examples:
List<string> items = null;
bool isEmpty = items.IsNullOrEmpty(); // true
items = new List<string>();
isEmpty = items.IsNullOrEmpty(); // true
// In a data processing system
public class DataProcessor
{
public void ProcessData(IEnumerable<DataRecord> records)
{
if (records.IsNullOrEmpty())
{
Console.WriteLine("No data to process");
return;
}
foreach (var record in records)
{
ProcessRecord(record);
}
}
}public static T FirstOrDefaultSafe<T>(this IEnumerable<T> source, T defaultValue = default)Purpose: Safely gets the first element or returns default value.
Examples:
List<int> numbers = new List<int> { 1, 2, 3 };
int first = numbers.FirstOrDefaultSafe(-1); // 1
List<int> empty = new List<int>();
int firstEmpty = empty.FirstOrDefaultSafe(-1); // -1
// In a query system
public class QueryService
{
public T GetFirstRecord<T>(IEnumerable<T> records, T defaultValue = default)
{
return records.FirstOrDefaultSafe(defaultValue);
}
public User GetActiveUser(IEnumerable<User> users)
{
return users.FirstOrDefault(u => u.IsActive, new User());
}
}public static IEnumerable<T> Page<T>(this IEnumerable<T> source, int page, int pageSize)Purpose: Gets a specific page of data from a collection.
Examples:
List<int> numbers = Enumerable.Range(1, 100).ToList();
IEnumerable<int> page1 = numbers.Page(1, 10); // 1-10
IEnumerable<int> page2 = numbers.Page(2, 10); // 11-20
// In a pagination system
public class PaginationService<T>
{
public PagedResult<T> GetPage(IEnumerable<T> items, int pageNumber, int pageSize)
{
var totalCount = items.Count();
var pagedItems = items.Page(pageNumber, pageSize);
return new PagedResult<T>
{
Items = pagedItems,
PageNumber = pageNumber,
PageSize = pageSize,
TotalCount = totalCount,
TotalPages = (int)Math.Ceiling((double)totalCount / pageSize)
};
}
}
public class PagedResult<T>
{
public IEnumerable<T> Items { get; set; }
public int PageNumber { get; set; }
public int PageSize { get; set; }
public int TotalCount { get; set; }
public int TotalPages { get; set; }
}public static int RemoveAll<T>(this IList<T> list, Predicate<T> match)Purpose: Removes all elements from an IList that satisfy the specified condition.
Examples:
List<string> items = new List<string> { "keep", "remove", "keep", "remove" };
int removed = items.RemoveAll(x => x == "remove"); // Returns 2
// In a data cleanup system
public class DataCleaner
{
public int RemoveInvalidRecords<T>(IList<T> records, Func<T, bool> isValid)
{
return records.RemoveAll(item => !isValid(item));
}
public int RemoveExpiredItems(IList<ExpirableItem> items)
{
return items.RemoveAll(item => item.IsExpired);
}
}Simplified HTTP status code handling and URL manipulation.
public static bool IsSuccessful(this HttpStatusCode statusCode)
public static bool IsClientError(this HttpStatusCode statusCode)
public static bool IsServerError(this HttpStatusCode statusCode)
public static bool IsError(this HttpStatusCode statusCode)
public static bool IsRedirect(this HttpStatusCode statusCode)
public static bool IsCaching(this HttpStatusCode statusCode)Examples:
HttpStatusCode status = HttpStatusCode.OK;
bool success = status.IsSuccessful(); // true
bool clientError = status.IsClientError(); // false
bool serverError = status.IsServerError(); // false
// In an HTTP client
public class ApiClient
{
public void HandleResponse(HttpResponseMessage response)
{
if (response.StatusCode.IsSuccessful())
{
Console.WriteLine("Request successful");
}
else if (response.StatusCode.IsClientError())
{
Console.WriteLine("Client error - check request parameters");
}
else if (response.StatusCode.IsServerError())
{
Console.WriteLine("Server error - try again later");
}
}
}public static Uri AddParameter(this Uri url, string parameterName, string parameterValue)Purpose: Adds a parameter to the query string of a URI.
Examples:
Uri baseUri = new Uri("https://api.example.com/users");
Uri withParam = baseUri.AddParameter("page", "1"); // https://api.example.com/users?page=1
Uri withMultiple = withParam.AddParameter("limit", "10"); // https://api.example.com/users?page=1&limit=10
// In an API client
public class ApiQueryBuilder
{
public Uri BuildQuery(string baseUrl, Dictionary<string, string> parameters)
{
Uri uri = new Uri(baseUrl);
foreach (var param in parameters)
{
uri = uri.AddParameter(param.Key, param.Value);
}
return uri;
}
}public static HttpRequestMessage Clone(this HttpRequestMessage original)
public static Task<HttpRequestMessage> CloneAsync(this HttpRequestMessage original, CancellationToken cancellationToken = default)Purpose: Creates a deep clone of an HttpRequestMessage.
Examples:
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com");
var clonedRequest = request.Clone();
// In a retry mechanism
public class RetryHandler
{
public async Task<HttpResponseMessage> ExecuteWithRetryAsync(HttpRequestMessage request, int maxRetries = 3)
{
for (int i = 0; i < maxRetries; i++)
{
try
{
var clonedRequest = await request.CloneAsync();
var response = await _httpClient.SendAsync(clonedRequest);
if (response.IsSuccessStatusCode)
{
return response;
}
response.Dispose();
}
catch
{
if (i == maxRetries - 1) throw;
}
await Task.Delay(1000 * (i + 1));
}
throw new InvalidOperationException("Max retries exceeded");
}
}Advanced LINQ operations with dynamic expression parsing.
public static Func<T, bool> GetExpressionDelegate<T>(this string stringExpression)Purpose: Parses a LINQ expression string into a compiled predicate function.
Examples:
string expression = "Age > 18 && Name.Contains('John')";
var predicate = expression.GetExpressionDelegate<Person>();
List<Person> people = GetPeople();
var adultsNamedJohn = people.Where(predicate);
// In a dynamic query system
public class DynamicQueryService<T>
{
public IEnumerable<T> FilterByExpression(IEnumerable<T> items, string expression)
{
var predicate = expression.GetExpressionDelegate<T>();
return items.Where(predicate);
}
public IEnumerable<T> ApplyUserFilter(IEnumerable<T> items, string userFilter)
{
if (string.IsNullOrEmpty(userFilter))
{
return items;
}
return FilterByExpression(items, userFilter);
}
}public static List<(Func<TSource, object>, bool)> GetOrderDelegates<TSource>(this string stringExpression)Purpose: Parses a LINQ expression string into a list of ordering delegates.
Examples:
string orderExpression = "Name DESC, Age ASC";
var orderDelegates = orderExpression.GetOrderDelegates<Person>();
// In a dynamic sorting system
public class DynamicSortService<T>
{
public IOrderedEnumerable<T> ApplySorting(IEnumerable<T> items, string sortExpression)
{
var orderDelegates = sortExpression.GetOrderDelegates<T>();
IOrderedEnumerable<T> ordered = null;
foreach (var (keySelector, descending) in orderDelegates)
{
ordered = ordered == null
? descending ? items.OrderByDescending(keySelector) : items.OrderBy(keySelector)
: descending ? ordered.ThenByDescending(keySelector) : ordered.ThenBy(keySelector);
}
return ordered ?? items.OrderBy(x => true);
}
}public static IEnumerable<TSource> Filter<TSource>(this IEnumerable<TSource> source, IDynamicFilterProvider<TSource>? filterProvider)
public static IEnumerable<TSource> Order<TSource>(this IEnumerable<TSource> source, IDynamicOrderProvider<TSource>? orderProvider)Purpose: Applies dynamic filtering and ordering using provider interfaces.
Examples:
// Using with PowerCSharp.Core interfaces
var filterProvider = new DynamicFilterProvider<Person>();
filterProvider.SetFilter(person => person.Age > 18);
var orderProvider = new DynamicOrderProvider<Person>();
orderProvider.SetOrderDelegates(new List<(Func<Person, object>, bool)>
{
(person => person.Name, false),
(person => person.Age, true)
});
var people = GetPeople();
var filtered = people.Filter(filterProvider);
var ordered = filtered.Order(orderProvider);
// In a data service
public class DataService<T>
{
public IEnumerable<T> GetData(IDynamicFilterProvider<T>? filterProvider = null,
IDynamicOrderProvider<T>? orderProvider = null)
{
var data = _repository.GetAll();
if (filterProvider != null)
{
data = data.Filter(filterProvider);
}
if (orderProvider != null)
{
data = data.Order(orderProvider);
}
return data;
}
}Simplified JSON and XML document manipulation.
public static JsonElement? Get(this JsonElement element, string name)
public static JsonElement? Get(this JsonElement element, int index)Purpose: Safely gets properties or array items from JsonElement.
Examples:
JsonElement element = JsonDocument.Parse("{\"name\":\"John\",\"age\":30}").RootElement;
var name = element.Get("name"); // JsonElement with value "John"
var age = element.Get("age"); // JsonElement with value 30
JsonArray array = JsonDocument.Parse("[1,2,3]").RootElement;
var first = array.Get(0); // JsonElement with value 1
// In a JSON processing service
public class JsonProcessingService
{
public string ExtractField(string json, string fieldName)
{
var document = JsonDocument.Parse(json);
var field = document.RootElement.Get(fieldName);
return field?.ValueToString() ?? string.Empty;
}
public List<string> ExtractArrayItems(string jsonArray)
{
var document = JsonDocument.Parse(jsonArray);
var items = new List<string>();
for (int i = 0; i < document.RootElement.GetArrayLength(); i++)
{
var item = document.RootElement.Get(i);
items.Add(item?.ValueToString() ?? string.Empty);
}
return items;
}
}public static bool TryGetPropertyCaseInsensitive(this JsonElement element, string propertyName, out JsonElement value)Purpose: Looks for a property using case-insensitive comparison.
Examples:
JsonElement element = JsonDocument.Parse("{\"NAME\":\"John\",\"AGE\":30}").RootElement;
bool found = element.TryGetPropertyCaseInsensitive("name", out var name); // true
bool foundAge = element.TryGetPropertyCaseInsensitive("age", out var age); // true
// In a flexible JSON parser
public class FlexibleJsonParser
{
public Dictionary<string, object> ParseToObject(string json)
{
var document = JsonDocument.Parse(json);
var result = new Dictionary<string, object>();
foreach (var property in document.RootElement.EnumerateObject())
{
if (element.TryGetPropertyCaseInsensitive(property.Name, out var value))
{
result[property.Name] = ExtractValue(value);
}
}
return result;
}
private object ExtractValue(JsonElement element)
{
return element.ValueKind switch
{
JsonValueKind.String => element.GetString(),
JsonValueKind.Number => element.GetDouble(),
JsonValueKind.True => true,
JsonValueKind.False => false,
_ => null
};
}
}public static Dictionary<string, object> Flatten(this XElement xmlElement)Purpose: Converts XML element to a flat dictionary representation.
Examples:
XElement xml = XElement.Parse("<root><child>value</child><attr>test</attr></root>");
var dict = xml.Flatten();
// Dictionary contains XML structure with attributes and nested elements
// In an XML processing service
public class XmlProcessingService
{
public Dictionary<string, object> ConvertXmlToDictionary(string xml)
{
var element = XElement.Parse(xml);
return element.Flatten();
}
public void ProcessXmlConfiguration(string xmlConfig)
{
var configDict = ConvertXmlToDictionary(xmlConfig);
foreach (var setting in configDict)
{
Console.WriteLine($"{setting.Key}: {setting.Value}");
}
}
}Enhanced object manipulation and type operations.
public static T ThrowOnNull<T>(this T? value) where T : classPurpose: Throws ArgumentNullException if the value is null.
Examples:
string text = null;
text.ThrowOnNull(); // Throws ArgumentNullException
// In a validation system
public class ParameterValidator
{
public void ValidateParameters(string name, object data)
{
name.ThrowOnNull();
data.ThrowOnNull();
// Continue with validation
}
}public static void CopyPropertiesTo<TSource, TDestination>(this TSource source, TDestination destination)
where TSource : class
where TDestination : classPurpose: Copies all matching properties by name and type from source to destination.
Examples:
var source = new Person { Name = "John", Age = 30 };
var destination = new Person();
source.CopyPropertiesTo(destination);
// In a data mapping service
public class MappingService
{
public TDestination Map<TSource, TDestination>(TSource source, TDestination destination)
where TSource : class
where TDestination : class
{
source.ThrowOnNull();
destination.ThrowOnNull();
source.CopyPropertiesTo(destination);
return destination;
}
public TDestination CreateMapped<TSource, TDestination>(TSource source)
where TSource : class
where TDestination : class, new()
{
var destination = new TDestination();
return Map(source, destination);
}
}public static Type? GetConcreteType(this Type interfaceType)Purpose: Returns the concrete Type that implements the specified interface type.
Examples:
Type concreteType = typeof(IMyInterface).GetConcreteType();
// In a plugin system
public class PluginLoader
{
public IEnumerable<Type> LoadPluginTypes<TInterface>()
{
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => typeof(TInterface).IsAssignableFrom(type) && !type.IsInterface)
.ToList();
}
public TInterface CreatePlugin<TInterface>(string typeName)
{
var interfaceType = typeof(TInterface);
var concreteType = interfaceType.GetConcreteType();
if (concreteType?.FullName == typeName)
{
return (TInterface)Activator.CreateInstance(concreteType);
}
throw new InvalidOperationException($"Plugin {typeName} not found");
}
}public static string ComputeHash(this object obj)Purpose: Computes a short hash string from any object by serializing it to JSON and applying SHA256 hashing. Handles serialization failures gracefully by generating a fallback hash based on the exception and type name.
Returns: A 16-character hexadecimal hash string representing the object's content. Returns "null" if the input object is null.
Examples:
var person = new { Name = "John", Age = 30, Email = "john@example.com" };
string hash = person.ComputeHash(); // "A1B2C3D4E5F67890"
// In a caching system
public class CacheManager
{
private readonly Dictionary<string, object> _cache = new();
public T GetOrCreate<T>(string key, Func<T> factory) where T : class
{
var cacheKey = $"{key}_{factory.GetHashCode()}";
if (_cache.TryGetValue(cacheKey, out var cached))
{
return (T)cached;
}
var item = factory();
_cache[cacheKey] = item;
return item;
}
public string GetObjectHash<T>(T obj) where T : class
{
return obj.ComputeHash();
}
}
// In a data integrity system
public class DataIntegrityChecker
{
public bool VerifyDataIntegrity<T>(T original, T current)
{
var originalHash = original.ComputeHash();
var currentHash = current.ComputeHash();
return originalHash == currentHash;
}
}CWE-73 compliant path operations with directory traversal protection.
public static string CombineAndValidate(string basePath, string relativePath)
public static string CombineAndValidate(string basePath, params string[] paths)Purpose: Combines path segments and validates the result to prevent directory traversal attacks (CWE-73). This method follows Veracode's recommended approach for path validation by canonicalizing the input and ensuring the result stays within the allowed base directory.
Returns: The validated absolute path that is guaranteed to be within the base directory.
Exceptions:
ArgumentNullException: Thrown when basePath or relativePath is nullArgumentException: Thrown when basePath or relativePath is emptySecurityException: Thrown when the combined path attempts directory traversal
Examples:
string basePath = "/var/www/uploads";
string userFile = "../../etc/passwd"; // Malicious attempt
try
{
// This will throw SecurityException due to directory traversal attempt
string safePath = PathExtensions.CombineAndValidate(basePath, userFile);
}
catch (SecurityException ex)
{
Console.WriteLine($"Security violation: {ex.Message}");
}
// Safe usage with valid relative paths
string validPath = PathExtensions.CombineAndValidate(basePath, "images/photo.jpg");
// Returns: "/var/www/uploads/images/photo.jpg"
// Multiple path segments
string multiPath = PathExtensions.CombineAndValidate(basePath, "documents", "2023", "report.pdf");
// Returns: "/var/www/uploads/documents/2023/report.pdf"
// In a file upload system
public class SecureFileUploader
{
private readonly string _baseUploadPath;
public SecureFileUploader(string baseUploadPath)
{
_baseUploadPath = baseUploadPath;
}
public string SaveUserFile(string userId, string fileName, Stream content)
{
var userFolder = Path.Combine(_baseUploadPath, "users", userId);
Directory.CreateDirectory(userFolder);
// Validate the path to prevent directory traversal
var safePath = PathExtensions.CombineAndValidate(userFolder, fileName);
using var fileStream = File.Create(safePath);
content.CopyTo(fileStream);
return safePath;
}
}
// In a document management system
public class DocumentManager
{
private readonly string _documentRoot;
public DocumentManager(string documentRoot)
{
_documentRoot = documentRoot;
}
public string GetDocumentPath(string category, string subcategory, string fileName)
{
// Combine multiple path segments safely
return PathExtensions.CombineAndValidate(_documentRoot, category, subcategory, fileName);
}
public bool ValidateDocumentPath(string requestedPath)
{
try
{
// This will throw if the path is outside the document root
var validatedPath = PathExtensions.CombineAndValidate(_documentRoot, requestedPath);
return true;
}
catch (SecurityException)
{
return false;
}
}
}public class EnhancedApiController : ControllerBase
{
protected IActionResult HandleResult<T>(Result<T> result)
{
if (result.IsSuccess)
{
return Ok(result.Data);
}
if (result.ErrorType == ErrorType.NotFound)
{
return NotFound(result.ErrorMessage);
}
if (result.ErrorType == ErrorType.Validation)
{
return BadRequest(result.ErrorMessage);
}
return StatusCode(500, result.ErrorMessage);
}
protected IActionResult HandlePagedResult<T>(PagedResult<T> result)
{
if (result.Items.IsNullOrEmpty())
{
return Ok(new { items = Array.Empty<T>(), totalCount = 0, pageNumber = result.PageNumber, pageSize = result.PageSize });
}
return Ok(new
{
items = result.Items,
totalCount = result.TotalCount,
pageNumber = result.PageNumber,
pageSize = result.PageSize,
totalPages = result.TotalPages
});
}
}public class DataProcessingPipeline<T>
{
private readonly List<Func<IEnumerable<T>, IEnumerable<T>>> _processors = new();
public DataProcessingPipeline<T> AddProcessor(Func<IEnumerable<T>, IEnumerable<T>> processor)
{
_processors.Add(processor);
return this;
}
public DataProcessingPipeline<T> Filter(Func<T, bool> predicate)
{
return AddProcessor(items => items.Where(predicate));
}
public DataProcessingPipeline<T> Transform(Func<T, T> transformer)
{
return AddProcessor(items => items.Select(transformer));
}
public DataProcessingPipeline<T> Sort(Func<T, IComparable> keySelector)
{
return AddProcessor(items => items.OrderBy(keySelector));
}
public DataProcessingPipeline<T> Page(int pageNumber, int pageSize)
{
return AddProcessor(items => items.Page(pageNumber, pageSize));
}
public IEnumerable<T> Execute(IEnumerable<T> source)
{
var result = source;
foreach (var processor in _processors)
{
result = processor(result);
}
return result;
}
}public class EnhancedConfigurationManager
{
private readonly IConfiguration _configuration;
private readonly ILogger<EnhancedConfigurationManager> _logger;
public EnhancedConfigurationManager(IConfiguration configuration, ILogger<EnhancedConfigurationManager> logger)
{
_configuration = configuration;
_logger = logger;
}
public T GetOptions<T>(string sectionName) where T : class, IAppOptions, new()
{
try
{
var options = _configuration.GetOptions<T>(sectionName);
if (options == null)
{
_logger.LogWarning("Configuration section {SectionName} not found, using defaults", sectionName);
return new T();
}
ValidateOptions(options);
return options;
}
catch (Exception ex)
{
_logger.LogError(ex, "Error loading configuration section {SectionName}", sectionName);
return new T();
}
}
private void ValidateOptions(IAppOptions options)
{
if (options is IValidatableOptions validatable)
{
validatable.Validate();
}
}
}- Avoid Repeated Enumerations: Cache enumerated results when used multiple times
- Use StringBuilder: For string operations that concatenate multiple strings
- LINQ Optimization: Use appropriate LINQ methods for specific scenarios
- Memory Allocation: Be aware of allocations in hot paths
- Null Checking: Always check for null before calling extension methods
- Error Handling: Provide meaningful error messages for invalid operations
- Documentation: Include comprehensive XML documentation for custom extensions
- Testing: Test edge cases and boundary conditions
- Restructured for cross-platform compatibility
- Moved ASP.NET Core specific extensions to PowerCSharp.Extensions.AspNetCore
- Enhanced .NET Standard 2.0 compatibility
- Updated dependency management for cross-platform support
- Initial release with comprehensive extension methods
- String manipulation and validation extensions
- Collection and LINQ enhancements
- JSON and XML processing extensions
- Object and type manipulation utilities
- Stream and exception handling extensions
- Performance-optimized implementations
- Async Extensions: Async versions of synchronous methods
- Validation Extensions: Enhanced validation patterns
- Caching Extensions: Built-in caching utilities
- Logging Extensions: Structured logging utilities
- Expression Tree Extensions: Advanced expression tree manipulation
- Reflection Extensions: Enhanced reflection utilities
- Parallel Extensions: Parallel processing utilities
- Memory Extensions: Memory pool and allocation utilities
For more information, see: