diff --git a/csharp/netfx.props b/csharp/netfx.props
deleted file mode 100644
index ca22ebeb7c..0000000000
--- a/csharp/netfx.props
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
- true
-
-
- /Library/Frameworks/Mono.framework/Versions/Current/lib/mono
- /usr/lib/mono
- /usr/local/lib/mono
-
-
- $(MonoBasePath)/4.5-api
- $(MonoBasePath)/4.5.1-api
- $(MonoBasePath)/4.5.2-api
- $(MonoBasePath)/4.6-api
- $(MonoBasePath)/4.6.1-api
- $(MonoBasePath)/4.6.2-api
- $(MonoBasePath)/4.7-api
- $(MonoBasePath)/4.7.1-api
- true
-
-
- $(FrameworkPathOverride)/Facades;$(AssemblySearchPaths)
-
-
diff --git a/csharp/sbe-dll/ThrowHelper.cs b/csharp/sbe-dll/ThrowHelper.cs
new file mode 100644
index 0000000000..30ca008c9c
--- /dev/null
+++ b/csharp/sbe-dll/ThrowHelper.cs
@@ -0,0 +1,47 @@
+using System;
+
+namespace Org.SbeTool.Sbe.Dll
+{
+ ///
+ /// Helper class that provides non-returning methods that throw common exception
+ /// from the generated C# code
+ ///
+ public class ThrowHelper
+ {
+ ///
+ /// Throws a when the "count" parameter is out of range
+ ///
+ /// the parameter that triggered the exception
+ public static void ThrowCountOutOfRangeException(int count) =>
+ throw new ArgumentOutOfRangeException("count", $"Outside allowed range: count={count}");
+
+ ///
+ /// Throws a when an invalid operation is invoked on a message (for example: enumerating a group past it's maximal count)
+ ///
+ public static void ThrowInvalidOperationException() =>
+ throw new InvalidOperationException();
+
+ ///
+ /// Throws a when the "index" parameter is out of range
+ ///
+ /// the parameter that triggered the exception
+ public static void ThrowIndexOutOfRangeException(int index) =>
+ throw new IndexOutOfRangeException($"index out of range: index={index}");
+
+ ///
+ /// Throws a when a too-small
+ /// is provided to a getter
+ ///
+ /// The length of the too-small Span
+ public static void ThrowWhenSpanLengthTooSmall(int length) =>
+ throw new ArgumentOutOfRangeException("dst", $"dst.Length={length} is too small.");
+
+ ///
+ /// Throws a when a too-large
+ /// is provided to a setter
+ ///
+ /// The length of the too-large Span
+ public static void ThrowWhenSpanLengthTooLarge(int length) =>
+ throw new ArgumentOutOfRangeException("src", $"src.Length={length} is too large.");
+ }
+}
\ No newline at end of file
diff --git a/csharp/sbe-dll/sbe-dll.csproj b/csharp/sbe-dll/sbe-dll.csproj
index a556ea09fd..252b6d9f3f 100644
--- a/csharp/sbe-dll/sbe-dll.csproj
+++ b/csharp/sbe-dll/sbe-dll.csproj
@@ -1,6 +1,4 @@
-
-
net45;netstandard2.0
True
@@ -23,7 +21,8 @@
-
+
+
diff --git a/csharp/sbe-tests/sbe-tests.csproj b/csharp/sbe-tests/sbe-tests.csproj
index 53eaca7da5..caf0e97279 100644
--- a/csharp/sbe-tests/sbe-tests.csproj
+++ b/csharp/sbe-tests/sbe-tests.csproj
@@ -1,6 +1,4 @@
-
-
net45;netcoreapp2.1
Org.SbeTool.Sbe.Tests
@@ -25,9 +23,10 @@
-
-
-
+
+
+
+
diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpGenerator.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpGenerator.java
index 9107c2c5fd..303474b9d7 100644
--- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpGenerator.java
+++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpGenerator.java
@@ -210,14 +210,16 @@ private void generateGroupClassHeader(
final String typeForBlockLength = cSharpTypeName(tokens.get(index + 2).encoding().primitiveType());
final String typeForNumInGroup = cSharpTypeName(numInGroupToken.encoding().primitiveType());
+ final String throwCondition = numInGroupToken.encoding().applicableMinValue().longValue() == 0 ?
+ "if ((uint) count > %3$d)\n" :
+ "if (count < %2$d || count > %3$d)\n";
+
sb.append(String.format("\n" +
indent + INDENT + "public void WrapForEncode(%1$s parentMessage, DirectBuffer buffer, int count)\n" +
indent + INDENT + "{\n" +
- indent + INDENT + INDENT + "if (count < %2$d || count > %3$d)\n" +
+ indent + INDENT + INDENT + throwCondition +
indent + INDENT + INDENT + "{\n" +
- indent + INDENT + INDENT + INDENT + "throw new ArgumentOutOfRangeException(\"count\",\n" +
- indent + INDENT + INDENT + INDENT + INDENT + "\"Outside allowed range: count=\" + count +\n" +
- indent + INDENT + INDENT + INDENT + INDENT + "\", min=%2$d, max=%3$d\");\n" +
+ indent + INDENT + INDENT + INDENT + "ThrowHelper.ThrowCountOutOfRangeException(count);\n" +
indent + INDENT + INDENT + "}\n\n" +
indent + INDENT + INDENT + "_parentMessage = parentMessage;\n" +
indent + INDENT + INDENT + "_buffer = buffer;\n" +
@@ -258,7 +260,7 @@ private void generateGroupEnumerator(final StringBuilder sb, final String groupN
indent + INDENT + "{\n" +
indent + INDENT + INDENT + "if (_index + 1 >= _count)\n" +
indent + INDENT + INDENT + "{\n" +
- indent + INDENT + INDENT + INDENT + "throw new InvalidOperationException();\n" +
+ indent + INDENT + INDENT + INDENT + "ThrowHelper.ThrowInvalidOperationException();\n" +
indent + INDENT + INDENT + "}\n\n" +
indent + INDENT + INDENT + "_offset = _parentMessage.Limit;\n" +
indent + INDENT + INDENT + "_parentMessage.Limit = _offset + _blockLength;\n" +
@@ -811,9 +813,9 @@ private CharSequence generateArrayProperty(
sb.append(String.format("\n" +
indent + "public %1$s Get%2$s(int index)\n" +
indent + "{\n" +
- indent + INDENT + "if (index < 0 || index >= %3$d)\n" +
+ indent + INDENT + "if ((uint) index >= %3$d)\n" +
indent + INDENT + "{\n" +
- indent + INDENT + INDENT + "throw new IndexOutOfRangeException(\"index out of range: index=\" + index);\n" +
+ indent + INDENT + INDENT + "ThrowHelper.ThrowIndexOutOfRangeException(index);\n" +
indent + INDENT + "}\n\n" +
"%4$s" +
indent + INDENT + "return _buffer.%5$sGet%8$s(_offset + %6$d + (index * %7$d));\n" +
@@ -825,9 +827,9 @@ private CharSequence generateArrayProperty(
sb.append(String.format("\n" +
indent + "public void Set%1$s(int index, %2$s value)\n" +
indent + "{\n" +
- indent + INDENT + "if (index < 0 || index >= %3$d)\n" +
+ indent + INDENT + "if ((uint) index >= %3$d)\n" +
indent + INDENT + "{\n" +
- indent + INDENT + INDENT + "throw new IndexOutOfRangeException(\"index out of range: index=\" + index);\n" +
+ indent + INDENT + INDENT + "ThrowHelper.ThrowIndexOutOfRangeException(index);\n" +
indent + INDENT + "}\n\n" +
indent + INDENT + "_buffer.%4$sPut%7$s(_offset + %5$d + (index * %6$d), value);\n" +
indent + "}\n",
@@ -852,8 +854,7 @@ private CharSequence generateArrayProperty(
indent + INDENT + "const int length = %2$d;\n" +
indent + INDENT + "if (dst.Length < length)\n" +
indent + INDENT + "{\n" +
- indent + INDENT + INDENT +
- "throw new ArgumentOutOfRangeException($\"dst.Length={dst.Length} is too large.\");\n" +
+ indent + INDENT + INDENT + "ThrowHelper.ThrowWhenSpanLengthTooSmall(dst.Length);\n" +
indent + INDENT + "}\n\n" +
"%3$s" +
indent + INDENT + "_buffer.GetBytes(_offset + %4$d, dst);\n" +
@@ -874,8 +875,7 @@ private CharSequence generateArrayProperty(
indent + INDENT + "const int length = %2$d;\n" +
indent + INDENT + "if (src.Length > length)\n" +
indent + INDENT + "{\n" +
- indent + INDENT + INDENT +
- "throw new ArgumentOutOfRangeException($\"src.Length={src.Length} is too large.\");\n" +
+ indent + INDENT + INDENT + "ThrowHelper.ThrowWhenSpanLengthTooLarge(src.Length);\n" +
indent + INDENT + "}\n\n" +
indent + INDENT + "_buffer.SetBytes(_offset + %3$d, src);\n" +
indent + "}\n",