From 9a0b53538f97d9d5b4bc3af072bd965c4c344075 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Tue, 1 Sep 2026 11:35:37 +0200 Subject: [PATCH 1/6] + DateOnlyExtensions.ToDateTime(DateTimeKind) --- BytecodeApi/Extensions/DateOnlyExtensions.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/BytecodeApi/Extensions/DateOnlyExtensions.cs b/BytecodeApi/Extensions/DateOnlyExtensions.cs index 2b76b08..32d6342 100644 --- a/BytecodeApi/Extensions/DateOnlyExtensions.cs +++ b/BytecodeApi/Extensions/DateOnlyExtensions.cs @@ -318,5 +318,16 @@ public DateTime ToDateTime() { return dateOnly.ToDateTime(default); } + /// + /// Returns a from this value. + /// + /// The to be used for creation of the object. + /// + /// The converted value. + /// + public DateTime ToDateTime(DateTimeKind kind) + { + return dateOnly.ToDateTime(default, kind); + } } } \ No newline at end of file From 5fa6f773d576e66c8e18e6fae7ee2d7fc6abb188 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Wed, 30 Sep 2026 16:53:03 +0200 Subject: [PATCH 2/6] + BytecodeApi.HandleableExceptionEventHandler --- .../Interop/KeyboardHookEventArgs.cs | 7 ++---- BytecodeApi/HandleableExceptionEventArgs.cs | 25 +++++++++++++++++++ .../HandleableExceptionEventHandler.cs | 8 ++++++ 3 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 BytecodeApi/HandleableExceptionEventArgs.cs create mode 100644 BytecodeApi/HandleableExceptionEventHandler.cs diff --git a/BytecodeApi.Win32/Interop/KeyboardHookEventArgs.cs b/BytecodeApi.Win32/Interop/KeyboardHookEventArgs.cs index 85e386c..ab49520 100644 --- a/BytecodeApi.Win32/Interop/KeyboardHookEventArgs.cs +++ b/BytecodeApi.Win32/Interop/KeyboardHookEventArgs.cs @@ -1,3 +1,4 @@ +using System.ComponentModel; using System.Windows.Forms; namespace BytecodeApi.Win32.Interop; @@ -5,7 +6,7 @@ namespace BytecodeApi.Win32.Interop; /// /// Provides data for the event. /// -public sealed class KeyboardHookEventArgs : EventArgs +public sealed class KeyboardHookEventArgs : HandledEventArgs { /// /// Gets the keycode of the pressed key. @@ -19,10 +20,6 @@ public sealed class KeyboardHookEventArgs : EventArgs /// Gets the key character, or '\0', if the key does not represent a printable character. /// public char KeyChar { get; } - /// - /// Gets or sets a value indicating whether to cancel the keyboard event. - /// - public bool Handled { get; set; } /// /// Initializes a new instance of the class. diff --git a/BytecodeApi/HandleableExceptionEventArgs.cs b/BytecodeApi/HandleableExceptionEventArgs.cs new file mode 100644 index 0000000..a8f10ff --- /dev/null +++ b/BytecodeApi/HandleableExceptionEventArgs.cs @@ -0,0 +1,25 @@ +using System.ComponentModel; + +namespace BytecodeApi; + +/// +/// Provides data for events that are raised when an unhandled exception occurs that can be handled by user code. +/// +public sealed class HandleableExceptionEventArgs : HandledEventArgs +{ + /// + /// Gets the unhandled exception that was raised. + /// + public Exception Exception { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The unhandled exception that was raised. + public HandleableExceptionEventArgs(Exception exception) + { + Check.ArgumentNull(exception); + + Exception = exception; + } +} \ No newline at end of file diff --git a/BytecodeApi/HandleableExceptionEventHandler.cs b/BytecodeApi/HandleableExceptionEventHandler.cs new file mode 100644 index 0000000..ef18f34 --- /dev/null +++ b/BytecodeApi/HandleableExceptionEventHandler.cs @@ -0,0 +1,8 @@ +namespace BytecodeApi; + +/// +/// Represents the method that is called when an unhandled exception occurs that can be handled by user code. +/// +/// The object that raised the event. +/// A that contains the event data. +public delegate void HandleableExceptionEventHandler(object sender, HandleableExceptionEventArgs e); \ No newline at end of file From 60c23d02c1a27d4e58a1fb456b992054bea29067 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Wed, 30 Sep 2026 19:01:06 +0200 Subject: [PATCH 3/6] + VersionExtensions --- BytecodeApi/Extensions/VersionExtensions.cs | 47 +++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 BytecodeApi/Extensions/VersionExtensions.cs diff --git a/BytecodeApi/Extensions/VersionExtensions.cs b/BytecodeApi/Extensions/VersionExtensions.cs new file mode 100644 index 0000000..c646dd9 --- /dev/null +++ b/BytecodeApi/Extensions/VersionExtensions.cs @@ -0,0 +1,47 @@ +namespace BytecodeApi.Extensions; + +/// +/// Provides a set of methods for interaction with objects. +/// +public static class VersionExtensions +{ + extension(Version version) + { + /// + /// Determines whether this instance is equal to another . + /// + /// The to compare to this instance. + /// The number of fields to compare. + /// + /// , if this instance is equal to the parameter; + /// otherwise, . + /// + public bool Equals(Version other, int fieldCount) + { + Check.ArgumentOutOfRange(fieldCount is >= 0 and <= 4, nameof(fieldCount), "Field count must be between 0 and 4."); + + return version.CompareTo(other, fieldCount) == 0; + } + /// + /// Compares this instance to a specified and returns a comparison of their relative values. + /// + /// A to compare with this instance. + /// The number of fields to compare. + /// + /// A value that indicates the relative order of the objects being compared. + /// + public int CompareTo(Version other, int fieldCount) + { + Check.ArgumentOutOfRange(fieldCount is >= 0 and <= 4, nameof(fieldCount), "Field count must be between 0 and 4."); + + int result; + + if (fieldCount >= 1 && (result = version.Major.CompareTo(other.Major)) != 0) return result; + if (fieldCount >= 2 && (result = version.Minor.CompareTo(other.Minor)) != 0) return result; + if (fieldCount >= 3 && (result = version.Build.CompareTo(other.Build)) != 0) return result; + if (fieldCount >= 4 && (result = version.Revision.CompareTo(other.Revision)) != 0) return result; + + return 0; + } + } +} \ No newline at end of file From bb810f4b8df3540fc5f88526af4159941596cebb Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Tue, 27 Oct 2026 19:32:06 +0100 Subject: [PATCH 4/6] + BytecodeApi.Data.Pagination --- BytecodeApi/Data/Pagination.cs | 51 ++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 BytecodeApi/Data/Pagination.cs diff --git a/BytecodeApi/Data/Pagination.cs b/BytecodeApi/Data/Pagination.cs new file mode 100644 index 0000000..6b0ee39 --- /dev/null +++ b/BytecodeApi/Data/Pagination.cs @@ -0,0 +1,51 @@ +namespace BytecodeApi.Data; + +/// +/// Provides information about the pagination of a collection of items. +/// +public sealed class Pagination +{ + /// + /// Gets or sets the zero based page index. + /// The default value is 0. + /// + public int Page { get; set; } + /// + /// Gets or sets the number of items included in a page. + /// The default value is 10. + /// + public int PageSize { get; set; } + /// + /// Gets or sets the total number of items, or , if the total number of items is unknown. + /// + public int? TotalCount { get; set; } + /// + /// Gets the total number of pages, or , if the total number of items is unknown. + /// + public int? PageCount => TotalCount is null or < 0 || PageSize <= 0 ? null : (TotalCount.Value + PageSize - 1) / PageSize; + /// + /// Gets the number of items to skip in order to get the items for the current page. + /// + public int Skip => Page * PageSize; + + /// + /// Initializes a new instance of the class. + /// + public Pagination() + { + PageSize = 10; + } + /// + /// Initializes a new instance of the class. + /// + /// The zero based page index. + /// The number of items included in a page. + public Pagination(int page, int pageSize) : this() + { + Check.ArgumentOutOfRangeEx.GreaterEqual0(page); + Check.ArgumentOutOfRangeEx.Greater0(pageSize); + + Page = page; + PageSize = pageSize; + } +} \ No newline at end of file From 3863a339c76b8fdd20b87aa0d97c91d635fe94c9 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Thu, 29 Oct 2026 10:27:08 +0100 Subject: [PATCH 5/6] EnumerableExtensions.OrderBy(ListSortDirection) overloads --- .../Extensions/EnumerableExtensions.cs | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/BytecodeApi/Extensions/EnumerableExtensions.cs b/BytecodeApi/Extensions/EnumerableExtensions.cs index e1c81eb..4446277 100644 --- a/BytecodeApi/Extensions/EnumerableExtensions.cs +++ b/BytecodeApi/Extensions/EnumerableExtensions.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.ComponentModel; namespace BytecodeApi.Extensions; @@ -627,6 +628,79 @@ public static IEnumerable Union(this IEnumerable firs return first.Union([second], comparer); } /// + /// Sorts the elements of a sequence in ascending or descending order, depending on the specified . + /// + /// The type of the elements of . + /// A sequence of values to sort. + /// Specifies the direction to sort (ascending or descending). + /// + /// An whose elements are sorted according to the specified direction. + /// + public static IOrderedEnumerable Order(this IEnumerable source, ListSortDirection direction) + { + return source.Order(direction, null); + } + /// + /// Sorts the elements of a sequence in ascending or descending order, depending on the specified . + /// + /// The type of the elements of . + /// A sequence of values to sort. + /// Specifies the direction to sort (ascending or descending). + /// An to compare the elements. + /// + /// An whose elements are sorted according to the specified direction. + /// + public static IOrderedEnumerable Order(this IEnumerable source, ListSortDirection direction, IComparer? comparer) + { + Check.ArgumentNull(source); + + return direction switch + { + ListSortDirection.Ascending => source.Order(comparer), + ListSortDirection.Descending => source.OrderDescending(comparer), + _ => throw Throw.InvalidEnumArgument(nameof(direction), direction), + }; + } + /// + /// Sorts the elements of a sequence in ascending or descending order, depending on the specified . + /// + /// The type of the elements of . + /// The type of the key returned by . + /// A sequence of values to sort. + /// A function to extract a key from an element. + /// Specifies the direction to sort (ascending or descending). + /// + /// An whose elements are sorted according to the specified direction. + /// + public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, ListSortDirection direction) + { + return source.OrderBy(keySelector, direction, null); + } + /// + /// Sorts the elements of a sequence in ascending or descending order, depending on the specified . + /// + /// The type of the elements of . + /// The type of the key returned by . + /// A sequence of values to sort. + /// A function to extract a key from an element. + /// Specifies the direction to sort (ascending or descending). + /// An to compare keys, or to use the default comparer. + /// + /// An whose elements are sorted according to the specified direction. + /// + public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, ListSortDirection direction, IComparer? comparer) + { + Check.ArgumentNull(source); + Check.ArgumentNull(keySelector); + + return direction switch + { + ListSortDirection.Ascending => source.OrderBy(keySelector, comparer), + ListSortDirection.Descending => source.OrderByDescending(keySelector, comparer), + _ => throw Throw.InvalidEnumArgument(nameof(direction), direction), + }; + } + /// /// Randomizes the order of the elements of a sequence. /// /// The type of the elements of . @@ -634,7 +708,7 @@ public static IEnumerable Union(this IEnumerable firs /// /// An whose elements are sorted in randomized order. /// - public static IOrderedEnumerable SortRandom(this IEnumerable source) + public static IOrderedEnumerable OrderRandom(this IEnumerable source) { Check.ArgumentNull(source); From c033caa94d54b452e5866cb6b5056cab61adb4c5 Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Thu, 29 Oct 2026 11:16:47 +0100 Subject: [PATCH 6/6] EnumerableExtensions.ThenBy(ListSortDirection) --- .../Extensions/EnumerableExtensions.cs | 43 +++++++++++++- BytecodeApi/Extensions/QueryableExtensions.cs | 57 +++++++++++++++++++ 2 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 BytecodeApi/Extensions/QueryableExtensions.cs diff --git a/BytecodeApi/Extensions/EnumerableExtensions.cs b/BytecodeApi/Extensions/EnumerableExtensions.cs index 4446277..9d30ceb 100644 --- a/BytecodeApi/Extensions/EnumerableExtensions.cs +++ b/BytecodeApi/Extensions/EnumerableExtensions.cs @@ -658,7 +658,7 @@ public static IOrderedEnumerable Order(this IEnumerable source.Order(comparer), ListSortDirection.Descending => source.OrderDescending(comparer), - _ => throw Throw.InvalidEnumArgument(nameof(direction), direction), + _ => throw Throw.InvalidEnumArgument(nameof(direction), direction) }; } /// @@ -697,7 +697,46 @@ public static IOrderedEnumerable OrderBy(this IEnumerabl { ListSortDirection.Ascending => source.OrderBy(keySelector, comparer), ListSortDirection.Descending => source.OrderByDescending(keySelector, comparer), - _ => throw Throw.InvalidEnumArgument(nameof(direction), direction), + _ => throw Throw.InvalidEnumArgument(nameof(direction), direction) + }; + } + /// + /// Performs a subsequent ordering of a sequence in ascending or descending order, depending on the specified . + /// + /// The type of the elements of . + /// The type of the key returned by . + /// A sequence of values to sort. + /// A function to extract a key from an element. + /// Specifies the direction to sort (ascending or descending). + /// + /// An whose elements are sorted according to the specified direction. + /// + public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, ListSortDirection direction) + { + return source.ThenBy(keySelector, direction, null); + } + /// + /// Performs a subsequent ordering of a sequence in ascending or descending order, depending on the specified . + /// + /// The type of the elements of . + /// The type of the key returned by . + /// A sequence of values to sort. + /// A function to extract a key from an element. + /// Specifies the direction to sort (ascending or descending). + /// An to compare keys, or to use the default comparer. + /// + /// An whose elements are sorted according to the specified direction. + /// + public static IOrderedEnumerable ThenBy(this IOrderedEnumerable source, Func keySelector, ListSortDirection direction, IComparer? comparer) + { + Check.ArgumentNull(source); + Check.ArgumentNull(keySelector); + + return direction switch + { + ListSortDirection.Ascending => source.ThenBy(keySelector, comparer), + ListSortDirection.Descending => source.ThenByDescending(keySelector, comparer), + _ => throw Throw.InvalidEnumArgument(nameof(direction), direction) }; } /// diff --git a/BytecodeApi/Extensions/QueryableExtensions.cs b/BytecodeApi/Extensions/QueryableExtensions.cs new file mode 100644 index 0000000..f41465a --- /dev/null +++ b/BytecodeApi/Extensions/QueryableExtensions.cs @@ -0,0 +1,57 @@ +using System.ComponentModel; +using System.Linq.Expressions; + +namespace BytecodeApi.Extensions; + +/// +/// Provides a set of methods for interaction with objects. +/// +public static class QueryableExtensions +{ + /// + /// Sorts the elements of a sequence in ascending or descending order, depending on the specified . + /// + /// The type of the elements of . + /// The type of the key returned by . + /// A sequence of values to sort. + /// A function to extract a key from an element. + /// Specifies the direction to sort (ascending or descending). + /// + /// An whose elements are sorted according to the specified direction. + /// + public static IOrderedQueryable OrderBy(this IQueryable source, Expression> keySelector, ListSortDirection direction) + { + Check.ArgumentNull(source); + Check.ArgumentNull(keySelector); + + return direction switch + { + ListSortDirection.Ascending => source.OrderBy(keySelector), + ListSortDirection.Descending => source.OrderByDescending(keySelector), + _ => throw Throw.InvalidEnumArgument(nameof(direction), direction) + }; + } + /// + /// Performs a subsequent ordering of a sequence in ascending or descending order, depending on the specified . + /// + /// The type of the elements of . + /// The type of the key returned by . + /// A sequence of values to sort. + /// A function to extract a key from an element. + /// Specifies the direction to sort (ascending or descending). + /// + /// An whose elements are sorted according to the specified direction. + /// + public static IOrderedQueryable ThenBy(this IOrderedQueryable source, Expression> keySelector, ListSortDirection direction) + { + Check.ArgumentNull(source); + Check.ArgumentNull(keySelector); + + return direction switch + { + ListSortDirection.Ascending => source.ThenBy(keySelector), + ListSortDirection.Descending => source.ThenByDescending(keySelector), + _ => throw Throw.InvalidEnumArgument(nameof(direction), direction) + }; + } +} \ No newline at end of file