diff --git a/src/Generator/AST/Utils.cs b/src/Generator/AST/Utils.cs
index 986b5585..9074614a 100644
--- a/src/Generator/AST/Utils.cs
+++ b/src/Generator/AST/Utils.cs
@@ -30,7 +30,7 @@ namespace CppSharp.AST
             var isEmptyCtor = method.IsConstructor && method.Parameters.Count == 0;
 
             var @class = method.Namespace as Class;
-            if (@class != null && @class.IsValueType && isEmptyCtor)
+            if (@class != null && @class.IsValueType && isEmptyCtor && !@class.HasNonTrivialDefaultConstructor)
                 return true;
 
             if (method.IsDestructor)
diff --git a/src/Generator/Generators/CLI/CLIHeaders.cs b/src/Generator/Generators/CLI/CLIHeaders.cs
index 035324b4..a143cf4d 100644
--- a/src/Generator/Generators/CLI/CLIHeaders.cs
+++ b/src/Generator/Generators/CLI/CLIHeaders.cs
@@ -798,7 +798,8 @@ namespace CppSharp.Generators.CLI
         public static bool FunctionIgnored(Function function)
         {
             return TypeIgnored(function.ReturnType.Type) ||
-                function.Parameters.Any(param => TypeIgnored(param.Type));
+                function.Parameters.Any(param => TypeIgnored(param.Type)) ||
+                function is Method { IsConstructor: true, Parameters: { Count: 0 }, Namespace: Class { IsValueType: true } };
         }
 
         public static bool TypeIgnored(CppSharp.AST.Type type)
diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs
index 617f8193..1abdb262 100644
--- a/src/Generator/Generators/CSharp/CSharpSources.cs
+++ b/src/Generator/Generators/CSharp/CSharpSources.cs
@@ -2678,7 +2678,7 @@ internal static{(@new ? " new" : string.Empty)} {printedClass} __GetInstance({Ty
                 if (hasBase && !@class.IsValueType)
                     WriteLineIndent($": this({(method != null ? "(void*) null" : "native")})");
 
-                if (@class.IsValueType)
+                if (@class.IsValueType && method.Parameters.Count > 0)
                     WriteLineIndent(": this()");
             }
 
diff --git a/src/Generator/Types/Std/Stdlib.CSharp.cs b/src/Generator/Types/Std/Stdlib.CSharp.cs
index 9047b97f..e394c40c 100644
--- a/src/Generator/Types/Std/Stdlib.CSharp.cs
+++ b/src/Generator/Types/Std/Stdlib.CSharp.cs
@@ -331,9 +331,6 @@ namespace CppSharp.Types.Std
                 string var;
                 if (ctx.ReturnVarName.LastIndexOf('.') > ctx.ReturnVarName.LastIndexOf("->"))
                 {
-                    ctx.Before.WriteLine("throw new NotImplementedException(\"This method cannot currently be called because it would " +
-                        "leave the object in an invalid state. See https://github.com/mono/CppSharp/issues/1777\");");
-
                     var = Generator.GeneratedIdentifier(ctx.ArgName);
                     ctx.Before.WriteLine($"fixed (void* {var} = &{ctx.ReturnVarName})");
                     ctx.Before.WriteOpenBraceAndIndent();
diff --git a/tests/dotnet/CSharp/CSharp.Tests.cs b/tests/dotnet/CSharp/CSharp.Tests.cs
index d2691b16..2c14bd92 100644
--- a/tests/dotnet/CSharp/CSharp.Tests.cs
+++ b/tests/dotnet/CSharp/CSharp.Tests.cs
@@ -2025,8 +2025,7 @@ public unsafe class CSharpTests
     }
 
     [Test]
-    [Ignore("https://github.com/mono/CppSharp/issues/1730")]
-    public void TestString()
+    public void TestValueTypeStringMember()
     {
         var test = new CSharp.ValueType();
         Assert.AreEqual(string.Empty, test.StringMember);
@@ -2036,4 +2035,29 @@ public unsafe class CSharpTests
         Assert.AreEqual("test", test.StringMember);
         Assert.AreEqual("test2", test.CharPtrMember);
     }
+
+    [Test]
+    [Ignore("https://github.com/mono/CppSharp/issues/1786")]
+    public void TestValueTypeStringMemberDefaulted()
+    {
+        CSharp.ValueType test = default;
+        Assert.AreEqual(string.Empty, test.StringMember);
+        Assert.AreEqual(null, test.CharPtrMember);
+        test.StringMember = "test";
+        test.CharPtrMember = "test2";
+        Assert.AreEqual("test", test.StringMember);
+        Assert.AreEqual("test2", test.CharPtrMember);
+    }
+
+    [Test]
+    public void TestValueTypeStringMemberDefaultedCtor()
+    {
+        var test = new CSharp.ValueTypeNoCtor();
+        Assert.AreEqual(string.Empty, test.StringMember);
+        Assert.AreEqual(null, test.CharPtrMember);
+        test.StringMember = "test";
+        test.CharPtrMember = "test2";
+        Assert.AreEqual("test", test.StringMember);
+        Assert.AreEqual("test2", test.CharPtrMember);
+    }
 }
diff --git a/tests/dotnet/CSharp/CSharp.h b/tests/dotnet/CSharp/CSharp.h
index 79bb99c0..88524469 100644
--- a/tests/dotnet/CSharp/CSharp.h
+++ b/tests/dotnet/CSharp/CSharp.h
@@ -1644,9 +1644,14 @@ inline void DLL_API InstantiateOptionalTemplate(Optional<unsigned int>, Optional
 
 CS_VALUE_TYPE class DLL_API ValueType {
 public:
-    // Parameterless ctors are currently not generated for value types.
-    ValueType(int) { }
+    ValueType() { }
 
     std::string string_member;
     const char* char_ptr_member;
 };
+
+CS_VALUE_TYPE class DLL_API ValueTypeNoCtor {
+public:
+    std::string string_member;
+    const char* char_ptr_member;
+};
diff --git a/tests/dotnet/Common/Common.CSharp.csproj b/tests/dotnet/Common/Common.CSharp.csproj
index a6968989..ab697a82 100644
--- a/tests/dotnet/Common/Common.CSharp.csproj
+++ b/tests/dotnet/Common/Common.CSharp.csproj
@@ -1 +1,5 @@
-<Project Sdk="Microsoft.NET.Sdk" />
\ No newline at end of file
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <LangVersion>11.0</LangVersion>
+  </PropertyGroup>
+</Project>
\ No newline at end of file