Problem
src/Mono.AndroidTools/Adb/AdbSyncNotification.cs is shipped product code — it compiles into Mono.AndroidTools.dll, which ships with the SDK (the assembly is added to _MSBuildFiles in build-tools/installers/create-installers.targets) — but it is not opted into nullable reference types (NRT). Its owning project, Mono.AndroidTools, does not set <Nullable> at the project level, so this file compiles in a nullable-oblivious context and gets no compile-time null-safety checking.
This is a small, self-contained notification/DTO class and a clean, low-risk candidate to opt in. The only genuinely-nullable member is LocalPath: callers in Adb/AdbSyncContext.cs pass null for the localPath argument for every directory / remove / preserve operation (e.g. new AdbSyncNotification (AdbSyncKind.CreateDirectory, entry.Key, null, 0)), and only pass a real path for copy operations. RemotePath, by contrast, is always given a non-null value (entry.Key, existingFile.FullPath). Adding NRT makes this existing contract explicit.
Location
- File(s):
src/Mono.AndroidTools/Adb/AdbSyncNotification.cs
- Line(s): line 1 (add directive), line 36 (constructor parameter), line 46 (property)
Current Code
public AdbSyncNotification (AdbSyncKind kind, string remotePath, string localPath, long size)
{
this.Kind = kind;
this.RemotePath = remotePath;
this.LocalPath = localPath;
this.Size = size;
}
public AdbSyncKind Kind { get; private set; }
public string RemotePath { get; private set; }
public string LocalPath { get; private set; }
public long Size { get; private set; }
Suggested Fix
The owning project (Mono.AndroidTools.csproj) targets netstandard2.0, so do not use ArgumentNullException.ThrowIfNull (it requires net6.0+). No null-throwing is needed here at all — only annotations.
- Add
#nullable enable as the very first line of the file (no preceding blank lines), matching the convention already used in src/Xamarin.AndroidTools/Debugging/ExecutionConfiguration.cs:
#nullable enable
//
// AdbSyncNotification.cs
- Make
LocalPath (and the matching constructor parameter) nullable, because callers legitimately pass null. Leave RemotePath non-nullable:
public AdbSyncNotification (AdbSyncKind kind, string remotePath, string? localPath, long size)
{
this.Kind = kind;
this.RemotePath = remotePath;
this.LocalPath = localPath;
this.Size = size;
}
public AdbSyncKind Kind { get; private set; }
public string RemotePath { get; private set; }
public string? LocalPath { get; private set; }
public long Size { get; private set; }
No other changes are required:
- The single constructor unconditionally assigns
RemotePath (non-null) and LocalPath (nullable), so there is no CS8618 (uninitialized non-nullable property).
GetMessage () only passes LocalPath to string.Format (...) (for the CopyFile / SkipCopyFile cases). Because this project targets netstandard2.0, the BCL is nullable-oblivious, so passing a string? there produces no warning.
- The value-type members (
Kind, Size, Redundant) and the computed IsRemove / IsCopyFile / IsCreateDirectory properties are unaffected.
- Callers in
Adb/AdbSyncContext.cs, Adb/AdbSyncClient.cs, and AndroidDevice.cs are not nullable-enabled, so making LocalPath nullable introduces no warnings at those call sites and no runtime change.
Guidelines
- Follow the repo's documented nullable reference type conventions.
- Never use the
! (null-forgiving) operator — annotate or check for null explicitly.
- The owning project targets
netstandard2.0: do not use ArgumentNullException.ThrowIfNull (x) (it does not exist before .NET 6). None is needed here.
- This file does not use
string.IsNullOrEmpty (...), so no IsNullOrEmpty () extension-method conversion is required.
- Keep Mono formatting style: tabs, space before
( and [. Preserve the existing license header.
- Scope strictly to this one file — do not modify
AdbSyncContext.cs, AdbSyncClient.cs, or AndroidDevice.cs.
Acceptance Criteria
Fix-finder metadata
- Script:
01-nullable-reference-types
- Score:
29/30 (actionability: 10, safety: 9, scope: 10)
Generated by Nightly Fix Finder · 1K AIC · ⌖ 50.2 AIC · ⊞ 40.8K · ◷
Problem
src/Mono.AndroidTools/Adb/AdbSyncNotification.csis shipped product code — it compiles intoMono.AndroidTools.dll, which ships with the SDK (the assembly is added to_MSBuildFilesinbuild-tools/installers/create-installers.targets) — but it is not opted into nullable reference types (NRT). Its owning project,Mono.AndroidTools, does not set<Nullable>at the project level, so this file compiles in a nullable-oblivious context and gets no compile-time null-safety checking.This is a small, self-contained notification/DTO class and a clean, low-risk candidate to opt in. The only genuinely-nullable member is
LocalPath: callers inAdb/AdbSyncContext.cspassnullfor thelocalPathargument for every directory / remove / preserve operation (e.g.new AdbSyncNotification (AdbSyncKind.CreateDirectory, entry.Key, null, 0)), and only pass a real path for copy operations.RemotePath, by contrast, is always given a non-null value (entry.Key,existingFile.FullPath). Adding NRT makes this existing contract explicit.Location
src/Mono.AndroidTools/Adb/AdbSyncNotification.csCurrent Code
Suggested Fix
The owning project (
Mono.AndroidTools.csproj) targetsnetstandard2.0, so do not useArgumentNullException.ThrowIfNull(it requiresnet6.0+). No null-throwing is needed here at all — only annotations.#nullable enableas the very first line of the file (no preceding blank lines), matching the convention already used insrc/Xamarin.AndroidTools/Debugging/ExecutionConfiguration.cs:LocalPath(and the matching constructor parameter) nullable, because callers legitimately passnull. LeaveRemotePathnon-nullable:No other changes are required:
RemotePath(non-null) andLocalPath(nullable), so there is noCS8618(uninitialized non-nullable property).GetMessage ()only passesLocalPathtostring.Format (...)(for theCopyFile/SkipCopyFilecases). Because this project targetsnetstandard2.0, the BCL is nullable-oblivious, so passing astring?there produces no warning.Kind,Size,Redundant) and the computedIsRemove/IsCopyFile/IsCreateDirectoryproperties are unaffected.Adb/AdbSyncContext.cs,Adb/AdbSyncClient.cs, andAndroidDevice.csare not nullable-enabled, so makingLocalPathnullable introduces no warnings at those call sites and no runtime change.Guidelines
!(null-forgiving) operator — annotate or check fornullexplicitly.netstandard2.0: do not useArgumentNullException.ThrowIfNull (x)(it does not exist before .NET 6). None is needed here.string.IsNullOrEmpty (...), so noIsNullOrEmpty ()extension-method conversion is required.(and[. Preserve the existing license header.AdbSyncContext.cs,AdbSyncClient.cs, orAndroidDevice.cs.Acceptance Criteria
#nullable enableis the first line ofAdbSyncNotification.cs(no preceding blank lines).LocalPathproperty and thelocalPathconstructor parameter are annotatedstring?;RemotePathremains non-nullablestring.!(null-forgiving) operator.Mono.AndroidToolsproject builds with no new warnings.Fix-finder metadata
01-nullable-reference-types29/30(actionability:10, safety:9, scope:10)