This repository contains the Base Class Library (BCL) for .NET nanoFramework — a free, open-source platform that enables writing managed .NET code for embedded systems and microcontrollers. The BCL provides the core System namespace types and is the nanoFramework equivalent of mscorlib.
- The code targets embedded systems (MCUs) with severe memory and flash constraints.
- Many methods are implemented in native C++ ("native stubs") and are declared with
[MethodImpl(MethodImplOptions.InternalCall)]— do not add a body to these methods. - Some standard .NET APIs are intentionally unsupported (throw
NotSupportedException) to preserve assembly/image size. Do not remove these stubs; they exist to satisfy interface contracts. - The library targets
TargetFrameworkVersion v1.0(the nanoFramework target, not desktop .NET).
| Project | Description | NuGet |
|---|---|---|
nanoFramework.CoreLibrary |
Full BCL with System.Reflection |
nanoFramework.CoreLibrary |
nanoFramework.CoreLibrary.NoReflection |
BCL without reflection (smaller flash footprint) | nanoFramework.CoreLibrary.NoReflection |
Both produce an assembly named mscorlib. The no-reflection variant excludes files under System/Reflection/ and sets no NANOCLR_REFLECTION define.
Projects use .nfproj files (nanoFramework MSBuild project system), not standard .csproj. These require Visual Studio with the nanoFramework VS extension installed, or MSBuild with NFProjectSystem.CSharp.targets.
nanoFramework.CoreLibrary/ # Main BCL project (with reflection)
System/ # All System.* source files
Collections/ # IEnumerable, ArrayList, generic interfaces
Diagnostics/ # Debug, Debugger, attributes
Globalization/ # CultureInfo, DateTimeFormatInfo, etc.
IO/ # IOException
Reflection/ # Assembly, MethodInfo, FieldInfo, etc.
Runtime/ # CompilerServices, InteropServices, Remoting
Threading/ # Thread, Monitor, Timer, WaitHandle, etc.
CoreLibrary.nfproj
Directory.Build.props
nanoFramework.CoreLibrary.NoReflection/ # BCL without reflection
System/ # Subset of System.* files (no Reflection/)
CoreLibrary.NoReflection.nfproj
Tests/ # Unit tests (one folder per test suite)
NFUnitTestArithmetic/
NFUnitTestArray/
NFUnitTestBitConverter/
NFUnitTestSystemLib/ # Covers most primitive types, strings, DateTime, etc.
NFUnitTestThread/
... (21 test suites total)
nanoFramework.TestFramework/ # Git submodule: test framework source
azure-pipelines.yml # CI/CD pipeline (Azure Pipelines, Windows)
nanoFramework.CoreLibrary.sln # Main solution (library + tests)
nanoFramework.CoreLibrary.Benchmarks.sln # Benchmarks solution
version.json # Nerdbank.GitVersioning configuration
- Windows only — the nanoFramework build toolchain runs on Windows (Azure Pipelines uses
windows-latest). - Visual Studio 2022 with the nanoFramework VS extension, or MSBuild 17+.
- NuGet packages are restored automatically;
packages.lock.jsonenforces locked restore in CI.
# Restore NuGet packages first
nuget restore nanoFramework.CoreLibrary.sln
# Build the solution (Release)
msbuild nanoFramework.CoreLibrary.sln /p:Configuration=Release /p:Platform="Any CPU"
# Build only CoreLibrary (Debug)
msbuild nanoFramework.CoreLibrary\CoreLibrary.nfproj /p:Configuration=DebugTests use the nanoFramework.TestFramework with the nanoCLR Win32 emulator (no real hardware needed by default).
# From Developer Command Prompt for VS 2022:
vstest.console.exe .\Tests\NFUnitTestBitConverter\bin\Release\NFUnitTest.dll ^
/Settings:.\.runsettings ^
/TestAdapterPath:.\nanoFramework.TestFramework\source\TestAdapter\bin\Debug\net4.8
# Run all tests using runsettings:
# .runsettings -> uses preview nanoCLR from NuGet (default)
# local_clr.runsettings -> uses a locally built nanoCLRKey runsettings config:
IsRealHardware=False— runs on emulatorUsePreviewClr=True— downloads latest preview nanoCLRMaxCpuCount=1— tests run sequentiallyTestSessionTimeout=1200000(20 min)
- Each test suite is a separate
.nfprojinTests/. - Use
nanoFramework.TestFrameworkattributes:[TestClass],[TestMethod],[Setup],[Cleanup],[DataRow]. - Do not reference the NuGet
nanoFramework.TestFramework— use the project reference fromnanoFramework.TestFramework/submodule instead (this is required for the CoreLibrary because it replaces mscorlib). - Do not reference
mscorlib,nanoFramework.TestFramework, ornanoFramework.UnitTestLauncherNuGet packages; use project references. - Every new API must have test coverage for all methods, properties, events, and exceptions.
Every .cs file must begin with:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.| Item | Convention | Example |
|---|---|---|
| Constants | PascalCase | MaxValue |
| Private/internal fields | _camelCase |
_thread |
| Private/internal static fields | s_camelCase |
s_instance |
| Public members | PascalCase | GetEnumerator |
- Indent: 4 spaces (C#), 2 spaces (XML/project files)
- Line endings: CRLF
- Encoding: UTF-8 BOM
- Always use braces, even for single-line blocks
usingdirectives outside namespace- System directives first
- Language version: C# 13.0 (main project);
defaultfor NoReflection variant - Avoid
var— use explicit types - Prefer expression-bodied members where appropriate
[MethodImpl(MethodImplOptions.InternalCall)]for native implementations — never add a body
- Avoid adding features that significantly increase binary size.
- Throw
NotSupportedException(without a message string) when a method cannot be implemented on the constrained target. - Comment rationale when omitting functionality for size reasons.
CI runs on Azure Pipelines (azure-pipelines.yml), not GitHub Actions. There is no GitHub Actions CI workflow for the main build. The pipeline:
- Builds
nanoFramework.CoreLibrary.slnon Windows - Runs all unit tests with nanoCLR emulator
- Packages and publishes two NuGet packages
- Updates dependent repositories on tag releases
- Avoid breaking native interop: Methods marked
[MethodImpl(MethodImplOptions.InternalCall)]have matching native C++ implementations in the nanoFramework interpreter. Changing their signatures requires coordinated changes to the native runtime. - Two-project sync: When adding or removing files from
nanoFramework.CoreLibrary, evaluate whether the same change applies tonanoFramework.CoreLibrary.NoReflection. Reflection-related files belong only in the main project. - Versioning: Versions are managed by Nerdbank.GitVersioning via
version.json. Do not manually edit version numbers. - Assembly signing: The assembly is strong-named with
key.snk. Do not replace or remove this file. Friends.cs: This file declaresInternalsVisibleToattributes for test projects. Add new test projects here if they need access to internals.
- The build requires Windows and the nanoFramework MSBuild extension. Running builds in a Linux environment (e.g., standard GitHub Actions) will fail because
NFProjectSystem.CSharp.targetsis not available there. - Tests must be run via
vstest.console.exewith the nanoFramework test adapter; standarddotnet testdoes not work. - The
RestoreLockedModeis enabled in CI to prevent unexpected package version changes — if packages need updating, thepackages.lock.jsonmust be regenerated and committed. - Some APIs intentionally throw
NotSupportedExceptionor return stub values — this is by design for embedded constraints, not a bug.