Skip to content

Commit eb1854d

Browse files
Merge pull request #46933 from dotnet/main
Merge main into live
2 parents d682369 + b3a3605 commit eb1854d

File tree

12 files changed

+156
-47
lines changed

12 files changed

+156
-47
lines changed

docs/azure/includes/dotnet-all.md

Lines changed: 9 additions & 8 deletions
Large diffs are not rendered by default.

docs/azure/includes/dotnet-new.md

Lines changed: 9 additions & 8 deletions
Large diffs are not rendered by default.

docs/core/compatibility/10.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ If you're migrating an app to .NET 10, the breaking changes listed here might af
7878
| [MSBUILDCUSTOMBUILDEVENTWARNING escape hatch removed](sdk/10.0/custom-build-event-warning.md) | Behavioral change | Preview 1 |
7979
| [MSBuild custom culture resource handling](sdk/10.0/msbuild-custom-culture.md) | Behavioral change | Preview 1 |
8080
| [NU1510 is raised for direct references pruned by NuGet](sdk/10.0/nu1510-pruned-references.md) | Source incompatible | Preview 1 |
81+
| [PackageReference without a version raises an error](sdk/10.0/nu1015-packagereference-version.md) | Behavioral change | Preview 6 |
8182
| [HTTP warnings promoted to errors in `dotnet package list` and `dotnet package search`](sdk/10.0/http-warnings-to-errors.md) | Behavioral/source incompatible change | Preview 4 |
8283

8384
## Windows Forms
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
title: "Breaking change - PackageReference without a version raises an error"
3+
description: "Learn about the breaking change in .NET 10 where PackageReference without a version raises NU1015 error instead of NU1604 warning."
4+
ms.date: 06/23/2025
5+
ai-usage: ai-assisted
6+
ms.custom: https://github.com/dotnet/docs/issues/46386
7+
---
8+
9+
# PackageReference without a version will raise an error
10+
11+
Starting in .NET 10, NuGet raises a [`NU1015` error](/nuget/reference/errors-and-warnings/nu1015) when a `PackageReference` item doesn't have a version specified, instead of the previous [`NU1604` warning](/nuget/reference/errors-and-warnings/nu1604).
12+
13+
There's no change when using Central Package Management, since by design the PackageReference XML should not have a version in that scenario.
14+
15+
## Version introduced
16+
17+
.NET 10 Preview 6
18+
19+
## Previous behavior
20+
21+
Previously, NuGet raised a NU1604 warning with the following text:
22+
23+
> Project dependency 'PackageA' does not contain an inclusive lower bound. Include a lower bound in the dependency version to ensure consistent restore results.
24+
25+
## New behavior
26+
27+
Starting in .NET 10, NuGet raises a NU1015 error with the following text:
28+
29+
> The following PackageReference item(s) do not have a version specified: PackageA
30+
31+
## Type of breaking change
32+
33+
This is a [behavioral change](../../categories.md#behavioral-change).
34+
35+
## Reason for change
36+
37+
The "no lower bound" message was confusing, and it was unclear how to fix the issue. Additionally, NuGet restored the lowest version for that package, which is rarely what developers want. This change provides clearer and more actionable error messages when the version metadata is missing.
38+
39+
## Recommended action
40+
41+
Add a version to the package reference, for example:
42+
43+
```diff
44+
- <PackageReference Include="Some.Package" />
45+
+ <PackageReference Include="Some.Package" Version="1.2.3" />
46+
```
47+
48+
If the lowest package version is desired, then use `Version="0.0.0"`. In this case, NuGet will raise warning NU1603, rather than the previous NU1604.
49+
50+
To revert to the previous warning, you can set `SdkAnalysisLevel` to `9.0.300` or lower. However, this will affect all features that gate on `SdkAnalysisLevel`.
51+
52+
## Affected APIs
53+
54+
None.

docs/core/compatibility/toc.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ items:
7474
href: sdk/10.0/msbuild-custom-culture.md
7575
- name: NU1510 is raised for direct references pruned by NuGet
7676
href: sdk/10.0/nu1510-pruned-references.md
77+
- name: PackageReference without a version raises error
78+
href: sdk/10.0/nu1015-packagereference-version.md
7779
- name: HTTP warnings promoted to errors in package list and search
7880
href: sdk/10.0/http-warnings-to-errors.md
7981
- name: Windows Forms
@@ -1984,6 +1986,8 @@ items:
19841986
href: sdk/10.0/msbuild-custom-culture.md
19851987
- name: NU1510 is raised for direct references pruned by NuGet
19861988
href: sdk/10.0/nu1510-pruned-references.md
1989+
- name: PackageReference without a version raises error
1990+
href: sdk/10.0/nu1015-packagereference-version.md
19871991
- name: HTTP warnings promoted to errors in package list and search
19881992
href: sdk/10.0/http-warnings-to-errors.md
19891993
- name: .NET 9

docs/core/extensions/file-globbing.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,37 @@ The preceding C# code:
141141

142142
The additional `Match` overloads work in similar ways.
143143

144+
### Ordered evaluation of include/exclude
145+
146+
By default, the matcher evaluates **all** include patterns first, then applies **all** exclude patterns, regardless of the order in which you added them. This means you can't re-include files that were previously excluded.
147+
148+
Starting in version 10 of the [📦 Microsoft.Extensions.FileSystemGlobbing package](https://www.nuget.org/packages/Microsoft.Extensions.FileSystemGlobbing), you can opt into *ordered* evaluation, where includes and excludes are processed exactly in the sequence they were added:
149+
150+
```csharp
151+
using Microsoft.Extensions.FileSystemGlobbing;
152+
153+
// Preserve the order of patterns when matching.
154+
Matcher matcher = new(preserveFilterOrder: true);
155+
156+
matcher.AddInclude("**/*"); // include everything
157+
matcher.AddExclude("logs/**/*"); // exclude logs
158+
matcher.AddInclude("logs/important/**/*"); // re-include important logs
159+
160+
var result = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(root)));
161+
foreach (var file in result.Files)
162+
{
163+
Console.WriteLine(file.Path);
164+
}
165+
```
166+
167+
In this mode, patterns are applied one after another:
168+
169+
- `**/*` adds all files.
170+
- `logs/**/*` filters out anything in `logs/`.
171+
- `logs/important/**/*` adds back only files under `logs/important/`.
172+
173+
Existing code that uses the default constructor will continue to run with the original "all includes, then all excludes" behavior.
174+
144175
## Pattern formats
145176

146177
The patterns that are specified in the `AddExclude` and `AddInclude` methods can use the following formats to match multiple files or directories.

docs/csharp/asynchronous-programming/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ You can start by updating the code so the thread doesn't block while tasks are r
4242

4343
:::code language="csharp" source="snippets/index/AsyncBreakfast-V2/Program.cs" ID="SnippetMain":::
4444

45-
The code updates the original method bodies of `FryEggs`, `FryBacon`, and `ToastBread` to return `Task<Egg>`, `Task<Bacon>`, and `Task<Toast>` objects, respectively. The updated method names include the "Async" suffix: `FryEggsAsync`, `FryBaconAsync`, and `ToastBreadAsync`. The `Main` method returns the `Task` object, although it doesn't have a `return` expression, which is by design. For more information, see [Evaluation of a void-returning async function](/dotnet/csharp/language-reference/language-specification/classes#14153-evaluation-of-a-void-returning-async-function).
45+
The code updates the original method bodies of `FryEggs`, `FryBacon`, and `ToastBread` to return `Task<Egg>`, `Task<Bacon>`, and `Task<Toast>` objects, respectively. The updated method names include the "Async" suffix: `FryEggsAsync`, `FryBaconAsync`, and `ToastBreadAsync`. The `Main` method returns the `Task` object, although it doesn't have a `return` expression, which is by design. For more information, see [Evaluation of a void-returning async function](/dotnet/csharp/language-reference/language-specification/classes#15144-evaluation-of-a-void-returning-async-function).
4646

4747
> [!NOTE]
4848
> The updated code doesn't yet take advantage of key features of asynchronous programming, which can result in shorter completion times. The code processes the tasks in roughly the same amount of time as the initial synchronous version. For the full method implementations, see the [final version of the code](#review-final-code) later in this article.

docs/csharp/misc/cs0060.md

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,40 @@
22
description: "Compiler Error CS0060"
33
title: "Compiler Error CS0060"
44
ms.date: 07/20/2015
5-
f1_keywords:
5+
f1_keywords:
66
- "CS0060"
7-
helpviewer_keywords:
7+
helpviewer_keywords:
88
- "CS0060"
99
ms.assetid: ae6d4fb7-5ff9-4883-82c3-f55b190f439a
1010
---
1111
# Compiler Error CS0060
1212

13-
Inconsistent accessibility: base class 'class1' is less accessible than class 'class2'
14-
15-
Class accessibility should be consistent between the base class and inherited class.
16-
17-
The following sample generates CS0060:
18-
19-
```csharp
20-
// CS0060.cs
21-
class MyClass
22-
// try the following line instead
23-
// public class MyClass
24-
{
25-
}
26-
27-
public class MyClass2 : MyClass // CS0060
28-
{
29-
public static void Main()
30-
{
31-
}
32-
}
33-
```
34-
13+
Inconsistent accessibility: base class 'Class1' is less accessible than class 'Class2'
14+
15+
In C#, a derived class cannot have broader accessibility than its base class. If the base class is less accessible, consumers of the derived class might unintentionally gain access to a class they shouldn't see.
16+
17+
Subclasses can never be more accessible than their base classes. That would allow consumers of the subclass broader access to the base type than was intended.
18+
19+
The following sample produces CS0060 because `Class1` is `internal` and `Class2` is `public`.
20+
21+
```csharp
22+
internal class Class1
23+
{
24+
}
25+
26+
public class Class2 : Class1 // 🛑 CS0060: Class1 is less accessible
27+
{
28+
}
29+
```
30+
31+
You can resolve CS0060 in one of two ways:
32+
33+
- Make the base class more accessible: Change `Class1` to be `public`.
34+
- Restrict the derived class's accessibility: Change `Class2` to be `internal`.
35+
36+
> [!TIP]
37+
> Base classes can be _more_ accessible than their subclasses, but never _less_ accessible.
38+
3539
## See also
3640

3741
- [Access Modifiers](../programming-guide/classes-and-structs/access-modifiers.md)

docs/fundamentals/runtime-libraries/snippets/System.Numerics/Complex/Overview/csharp/Project.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFrameworks>net9</TargetFrameworks>
5+
<TargetFramework>net9.0</TargetFramework>
66
</PropertyGroup>
77

88
</Project>

docs/fundamentals/runtime-libraries/snippets/System.Numerics/Complex/Overview/csharp/customfmt1.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,19 @@ public string Format(string format, object arg,
3333
fmtString = "N" + precision.ToString();
3434
}
3535
if (format.Substring(0, 1).Equals("I", StringComparison.OrdinalIgnoreCase))
36-
return c1.Real.ToString(fmtString) + " + " + c1.Imaginary.ToString(fmtString) + "i";
36+
{
37+
// Determine the sign to display.
38+
char sign = c1.Imaginary < 0 ? '-' : '+';
39+
// Display the determined sign and the absolute value of the imaginary part.
40+
return c1.Real.ToString(fmtString) + " " + sign + " " + Math.Abs(c1.Imaginary).ToString(fmtString) + "i";
41+
}
3742
else if (format.Substring(0, 1).Equals("J", StringComparison.OrdinalIgnoreCase))
38-
return c1.Real.ToString(fmtString) + " + " + c1.Imaginary.ToString(fmtString) + "j";
43+
{
44+
// Determine the sign to display.
45+
char sign = c1.Imaginary < 0 ? '-' : '+';
46+
// Display the determined sign and the absolute value of the imaginary part.
47+
return c1.Real.ToString(fmtString) + " " + sign + " " + Math.Abs(c1.Imaginary).ToString(fmtString) + "j";
48+
}
3949
else
4050
return c1.ToString(format, provider);
4151
}

0 commit comments

Comments
 (0)