Known Limitations

Platform gaps, missing features, stub-only classes, and known differences from .NET.

No Garbage Collector

sharp-runtime has no garbage collector. System::GC is a stub that does nothing. All memory management is explicit C++ RAII. This is intentional — GC adds complexity and latency that is unacceptable in game runtime code (the primary use case via CNA).

Impact: Circular reference cycles with shared_ptr cause memory leaks. Code that assumes GC will clean up must be refactored to use RAII patterns.

POSIX-only Subsystems

The following subsystems work on Linux, macOS, and Android (via NDK) only:

SubsystemReasonWindows/Emscripten status
System::Net::SocketsUses POSIX socket APIsNot implemented
System::IO::RandomAccessUses pread/pwriteHas Win32 fallback (needs verification)
System::AppDomainUses POSIX process/env APIsNot fully implemented
System::AppContextUses POSIX pathsNot fully implemented
System::TimeZoneInfoUses localtime_r, /usr/share/zoneinfoNot portable

No Reflection

System::Type is a stub. There is no runtime type metadata, no dynamic method invocation, no Activator.CreateInstance, and no attribute inspection at runtime. Only GetTypeName() (returns a string) is available for type identification. See Reflection.

Stub-only Classes

These classes exist as headers for API compatibility but have minimal or no implementation:

ClassNotes
System::GCNo garbage collection; all methods are no-ops
System::TypeNo runtime type metadata
System::ActivatorCreateInstance not implementable without reflection
System::Threading::SynchronizationContextStub; Progress<T> calls handlers synchronously
System::Diagnostics::StackTraceNo stack capture
System::Diagnostics::StackFrameNo frame info
Attribute classes (all)Exist for syntax, no runtime effect

HttpClient — No TLS / HTTPS

System::Net::Http::HttpClient is implemented but supports plain HTTP only. HTTPS (TLS/SSL) is not implemented. Do not use for production HTTPS requests. A future improvement would require linking an SSL library (e.g., OpenSSL or mbedTLS) which has not been approved as a dependency yet.

Regex Limitations

System::Text::RegularExpressions::Regex uses std::regex as its backend. Known limitations compared to .NET Regex:

No LINQ

There is no LINQ implementation. C# code using .Where(), .Select(), .GroupBy(), etc. must be rewritten as explicit loops or use C++ standard algorithm functions (std::find_if, std::transform, etc.).

No C# async/await Syntax

C# async/await coroutines have no direct language equivalent in C++. Task and ValueTask APIs are provided by the SharpRuntime::Threading.Tasks component, but they do not reproduce the full C# awaitable pattern. Ported asynchronous code may need threads, callbacks, or a C++-native asynchronous design.

SynchronizationContext

System::Threading::SynchronizationContext is a stub. Progress<T> calls its handlers synchronously rather than marshalling them to a context. For single-threaded game use (the primary use case) this is the correct behavior.

AppDomain — Linux-only getBaseDirectory

AppDomain::getBaseDirectoryProperty() reads /proc/self/exe to determine the executable path. This works on Linux but not on macOS (which uses _NSGetExecutablePath) or Windows. The method may return an incorrect or empty path on non-Linux platforms.

Additionally, extern char** environ in Environment.cpp must remain at file scope (not inside namespace System) — moving it causes a PIE relocation error.

String Encoding Differences

No String Null

In C#, a string variable can be null. In sharp-runtime, std::string cannot be null — the convention is to use empty string ("") where C# would use null.

Array Fixed Size

C# arrays are fixed-size after creation. std::vector<T> is dynamic. While this is more flexible, code that relies on array length staying constant must be careful not to accidentally resize the vector.

No Checked Arithmetic

C# has checked / unchecked contexts for integer overflow detection. C++ has no equivalent. Integer overflow is undefined behavior for signed types in C++ — use OverflowException manually if overflow detection is needed.

Thread Safety

Thread safety of individual classes is not guaranteed unless explicitly documented. The standard collections (List<T>, Dictionary<K,V>, etc.) are not thread-safe for concurrent writes — use System::Collections::Concurrent types or external synchronization.

WeakReference Generic Form

WeakReferenceT<T> is the generic form (not WeakReference<T>) because C++ cannot have a class template and a plain class with the same name in the same namespace. Replace WeakReference<T> with WeakReferenceT<T> when porting.

Emscripten Build

Emscripten (WebAssembly) compilation has never been CI-tested in this repository. Platform guards exist but are not validated. POSIX-only subsystems would fail to link.