Skip to content

Update Nice3point.Revit.Extensions - #79

Merged
Nice3point merged 1 commit into
developfrom
renovate/nice3point.revit.extensions
Jul 26, 2026
Merged

Update Nice3point.Revit.Extensions#79
Nice3point merged 1 commit into
developfrom
renovate/nice3point.revit.extensions

Conversation

@Nice3point

Copy link
Copy Markdown
Owner

This PR contains the following updates:

Package Type Update Change
Nice3point.Revit.Extensions nuget patch 2021.5.22021.5.3
Nice3point.Revit.Extensions nuget patch 2022.5.22022.5.3
Nice3point.Revit.Extensions nuget patch 2023.5.22023.5.3
Nice3point.Revit.Extensions nuget patch 2024.3.22024.3.3
Nice3point.Revit.Extensions nuget patch 2025.2.22025.2.3
Nice3point.Revit.Extensions nuget patch 2026.1.22026.1.3
Nice3point.Revit.Extensions nuget patch 2027.0.22027.0.3

Release Notes

Nice3point/RevitExtensions (Nice3point.Revit.Extensions)

v2027.0.3

Compare Source

This update focuses on making Revit collections and maps enumerable the way the rest of .NET is.

The Revit API mirrors the native C++ containers. A collection stops its contract at the non-generic IEnumerable.
A foreach over it yields object and every LINQ query opens with a cast.
A map goes further and keeps the key of the current entry on the concrete iterator instead of in the enumeration, so a foreach never sees the key at all.
Reading the keys means a hand-written loop over ForwardIterator(), and that iterator holds a native handle until it is disposed.

Iterating a map used to take a loop:

var iterator = document.ParameterBindings.ForwardIterator();
while (iterator.MoveNext())
{
    var definition = iterator.Key;
    var binding = (Binding)iterator.Current;
}

Now the key travels with the value, and the iterator is disposed for you:

foreach (var (definition, binding) in document.ParameterBindings.EnumerateEntries())
{
}

Looking up a value used to take two calls, and the indexer is reachable only through get_Item:

if (element.ParametersMap.Contains("Comments"))
{
    var parameter = element.ParametersMap.get_Item("Comments");
}

Now it takes one:

if (element.ParametersMap.TryGetValue("Comments", out var parameter))
{
}

Collections used to name their element type at every call site:

foreach (Face face in solid.Faces)
{
}

var areas = solid.Faces.Cast<Face>().Select(face => face.Area);

var names = categorySet.Cast<Category>().Select(category => category.Name);

Now the element type comes from the collection:

foreach (var face in solid.Faces.EnumerateValues())
{
}

var areas = solid.Faces.EnumerateValues().Select(face => face.Area);

var names = categorySet.EnumerateValues().Select(category => category.Name);

New Extensions

Maps

Available on DefinitionBindingMap and BindingMap, ParameterMap, CategoryNameMap, and Categories:

  • map.EnumerateEntries()
  • map.EnumerateKeys()
  • map.EnumerateValues()
  • map.TryGetValue(key, out value)
Collections

Available on every array and every set holding elements of a single type, 51 of them:

  • curveArray.EnumerateValues()
  • faceArray.EnumerateValues()
  • elementArray.EnumerateValues()
  • categorySet.EnumerateValues()
  • parameterSet.EnumerateValues()
  • viewSet.EnumerateValues()

Performance

Reading a collection the short way is also the fast way.
EnumerateValues() is not a wrapper over Cast<T>().

An array exposes its size and an indexed accessor, the enumeration reads every element by its index and spends one interop call per element.
A Cast<T>() over the same array walks a native iterator and spends two.
A set exposes no index, the enumeration walks the enumerator itself and drops the LINQ layer above it.

A map keeps the key of the current entry on its iterator and the value on Current, so building a pair costs two interop calls.
EnumerateKeys() and EnumerateValues() read only the side you ask for and pay for one.

Measured on Revit 2027 over an array of 1000 curves, a set of 600 categories, and the parameter map of a level:

Enumeration Replaces Faster Allocates less
array.EnumerateValues() array.Cast<Curve>() 10%
set.EnumerateValues() set.Cast<Category>() 5%
map.EnumerateKeys() enumerating the pairs 30% 35%
map.EnumerateValues() enumerating the pairs 23% 35%

The worst case is a set, 5% faster for the same allocation.
The best case is a map key enumeration, 30% faster and 35% fewer bytes.
The benchmark and its results in EnumerationBenchmark.


Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

Copilot AI review requested due to automatic review settings July 26, 2026 18:53
@Nice3point Nice3point added the maintenance ⚙️ Some regular maintenance updates label Jul 26, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the centrally managed Revit-dependent Nice3point.Revit.Extensions NuGet package versions across supported Revit year configurations, keeping the toolkit’s dependency matrix in sync with the latest patch releases.

Changes:

  • Bumps Nice3point.Revit.Extensions for Revit 2021–2027 to the next patch version (*.x.2*.x.3).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Nice3point
Nice3point merged commit 4a4796d into develop Jul 26, 2026
2 checks passed
@Nice3point
Nice3point deleted the renovate/nice3point.revit.extensions branch July 26, 2026 19:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintenance ⚙️ Some regular maintenance updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants