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:
| Subsystem | Reason | Windows/Emscripten status |
|---|---|---|
System::Net::Sockets | Uses POSIX socket APIs | Not implemented |
System::IO::RandomAccess | Uses pread/pwrite | Has Win32 fallback (needs verification) |
System::AppDomain | Uses POSIX process/env APIs | Not fully implemented |
System::AppContext | Uses POSIX paths | Not fully implemented |
System::TimeZoneInfo | Uses localtime_r, /usr/share/zoneinfo | Not 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:
| Class | Notes |
|---|---|
System::GC | No garbage collection; methods are no-ops |
System::Type | No runtime type metadata |
System::Diagnostics::StackTrace | No stack capture |
System::Diagnostics::StackFrame | No frame info |
| Attribute classes (all) | Exist for syntax, no runtime effect |
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 async/await
C# async/await coroutines have no direct equivalent. System::Threading::Tasks::Task
is partially implemented but does not provide the full awaitable pattern.
Asynchronous code must be refactored to use threads, callbacks, or synchronous execution.
String Encoding Differences
- C#
stringis UTF-16; sharp-runtimestd::stringis UTF-8 by convention - C#
charis 16-bit;charcs=char16_tin sharp-runtime - String
Lengthin .NET = UTF-16 code units;size()in C++ = bytes - Multi-byte UTF-8 characters will have
size()> character count
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.
Networking (TODO)
Per TODO.md, the following networking classes are planned but not yet fully implemented:
- Full
TcpClientimplementation UdpSocketPacketabstractionNetStreamNetServer/NetClient