iter = parsed_options.find("serial");
       serialize_ = (iter != parsed_options.end());
       if (serialize_) {
-       wcf_namespace_ = iter->second;  // since there can be only one namespace
+        wcf_namespace_ = iter->second;  // since there can be only one namespace
       }
       
       iter = parsed_options.find("wcf");
       wcf_ = (iter != parsed_options.end());
       if (wcf_) {
-       wcf_namespace_ = iter->second;
+        wcf_namespace_ = iter->second;
       }
 
       out_dir_base_ = "gen-csharp";
   vector<t_enum_value*> constants = tenum->get_constants();
   vector<t_enum_value*>::iterator c_iter;
   for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
-       generate_csharp_doc(f_enum, *c_iter);
+        generate_csharp_doc(f_enum, *c_iter);
 
     int value = (*c_iter)->get_value();
     indent(f_enum) << (*c_iter)->get_name() << " = " << value << "," << endl;
       // if it is not required, if it has a default value, we need to generate Isset
       // if we are not nullable, then we generate Isset
       if (!is_required && (!nullable_ || has_default)) {
-       indent(out) << "public bool " << (*m_iter)->get_name() << ";" << endl;
+        indent(out) << "public bool " << (*m_iter)->get_name() << ";" << endl;
       }
     }
 
       bool is_required = field_is_required((*f_iter));
       bool has_default = field_has_default((*f_iter));
       if (nullable_ && !has_default && !is_required) {
-       indent(out) << "if (" << prop_name((*f_iter)) << " != null) {" << endl;
-       indent_up();
+        indent(out) << "if (" << prop_name((*f_iter)) << " != null) {" << endl;
+        indent_up();
       } else if (!is_required) {
-       bool null_allowed = type_can_be_null((*f_iter)->get_type());
-       if (null_allowed) {
-         indent(out) <<
-           "if (" << prop_name((*f_iter)) << " != null && __isset." << (*f_iter)->get_name() << ") {" << endl;
-         indent_up();
-       } else {
-         indent(out) <<
-           "if (__isset." << (*f_iter)->get_name() << ") {" << endl;
-         indent_up();
-       }
+        bool null_allowed = type_can_be_null((*f_iter)->get_type());
+        if (null_allowed) {
+          indent(out) <<
+            "if (" << prop_name((*f_iter)) << " != null && __isset." << (*f_iter)->get_name() << ") {" << endl;
+          indent_up();
+        } else {
+          indent(out) <<
+            "if (__isset." << (*f_iter)->get_name() << ") {" << endl;
+          indent_up();
+        }
       }
       indent(out) << "field.Name = \"" << (*f_iter)->get_name() << "\";" << endl;
       indent(out) << "field.Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl;
 
       indent(out) << "oprot.WriteFieldEnd();" << endl;
       if (!is_required) {
-       indent_down();
-       indent(out) << "}" << endl;
+        indent_down();
+        indent(out) << "}" << endl;
       }
     }
   }
       }
       
       if (nullable_) {
-       out << "(this." << prop_name((*f_iter)) << " != null) {" << endl;
+        out << "(this." << prop_name((*f_iter)) << " != null) {" << endl;
       } else {
-       out <<
-         "(this.__isset." << (*f_iter)->get_name() << ") {" << endl;
+        out << "(this.__isset." << (*f_iter)->get_name() << ") {" << endl;
       }
       indent_up();
 
         "oprot.WriteFieldEnd();" << endl;
 
       if (null_allowed) {
-       indent_down();
-       indent(out) << "}" << endl;
+        indent_down();
+        indent(out) << "}" << endl;
       }
 
       indent_down();
   indent_up();
 
   indent(out) <<
-    "StringBuilder sb = new StringBuilder(\"" << tstruct->get_name() << "(\");" << endl;
+    "StringBuilder __sb = new StringBuilder(\"" << tstruct->get_name() << "(\");" << endl;
 
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
-  bool first = true;
+  indent(out) << "bool __first = true;" << endl;
+  bool had_required = false;  // set to true after first required field has been processed
 
   for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    if (first) {
-      first = false;
+    bool is_required = field_is_required((*f_iter));
+    bool has_default = field_has_default((*f_iter));
+    if (nullable_ && !has_default && !is_required) {
+      indent(out) << "if (" << prop_name((*f_iter)) << " != null) {" << endl;
+      indent_up();
+    } else if (!is_required) {
+      bool null_allowed = type_can_be_null((*f_iter)->get_type());
+      if (null_allowed) {
+        indent(out) <<
+          "if (" << prop_name((*f_iter)) << " != null && __isset." << (*f_iter)->get_name() << ") {" << endl;
+        indent_up();
+      } else {
+        indent(out) <<
+          "if (__isset." << (*f_iter)->get_name() << ") {" << endl;
+        indent_up();
+      }
+    }
+
+    if( ! had_required)        {
+      indent(out) << "if(!__first) { __sb.Append(\", \"); }" << endl;
+         if( ! is_required) {
+        indent(out) << "__first = false;" << endl;
+         }
       indent(out) <<
-        "sb.Append(\"" << prop_name((*f_iter)) << ": \");" << endl;
+        "__sb.Append(\"" << prop_name((*f_iter)) << ": \");" << endl;
     } else {
       indent(out) <<
-        "sb.Append(\"," << prop_name((*f_iter)) << ": \");" << endl;
-    }
+        "__sb.Append(\", " << prop_name((*f_iter)) << ": \");" << endl;
+       }
+        
+          
     t_type* ttype = (*f_iter)->get_type();
     if (ttype->is_xception() || ttype->is_struct()) {
       indent(out) <<
-        "sb.Append(" << prop_name((*f_iter)) << "== null ? \"<null>\" : "<< prop_name((*f_iter))  << ".ToString());" << endl;
+        "__sb.Append(" << prop_name((*f_iter)) << "== null ? \"<null>\" : "<< prop_name((*f_iter))  << ".ToString());" << endl;
     } else {
       indent(out) <<
-        "sb.Append(" << prop_name((*f_iter))  << ");" << endl;
+        "__sb.Append(" << prop_name((*f_iter))  << ");" << endl;
+    }
+        
+    if (!is_required) {
+      indent_down();
+      indent(out) << "}" << endl;
+    } else {
+      had_required = true;  // now __first must be false, so we don't need to check it anymore
     }
   }
 
   indent(out) <<
-    "sb.Append(\")\");" << endl;
+    "__sb.Append(\")\");" << endl;
   indent(out) <<
-    "return sb.ToString();" << endl;
+    "return __sb.ToString();" << endl;
 
   indent_down();
   indent(out) << "}" << endl << endl;
       out << "(!__isset." << (*f_iter)->get_name() << " ? 0 : ";
     }
     if (ttype->is_container()) {
-       out << "(TCollections.GetHashCode("
-               << prop_name((*f_iter))
-               << "))";
+            out << "(TCollections.GetHashCode("
+                    << prop_name((*f_iter))
+                    << "))";
     } else {
-               out << "("
-                       << prop_name((*f_iter))
-                       << ".GetHashCode())";
+                out << "("
+                        << prop_name((*f_iter))
+                        << ".GetHashCode())";
     }
     out << ");" << endl;
   }
   generate_csharp_doc(f_service_, tservice);
 
   if (wcf_) {
-         indent(f_service_) <<
-               "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
+          indent(f_service_) <<
+                "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
   }
   indent(f_service_) <<
     "public interface Iface" << extends_iface << " {" << endl;
   vector<t_function*>::iterator f_iter;
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter)
   {
-       generate_csharp_doc(f_service_, *f_iter);
-
-       // if we're using WCF, add the corresponding attributes
-       if (wcf_) {
-               indent(f_service_) <<
-                       "[OperationContract]" << endl;
-
-               const std::vector<t_field*>& xceptions = (*f_iter)->get_xceptions()->get_members();
-               vector<t_field*>::const_iterator x_iter;
-               for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-                 indent(f_service_) << "[FaultContract(typeof(" + type_name((*x_iter)->get_type(), false, false) + "Fault))]" << endl;
-               }
-       }
+        generate_csharp_doc(f_service_, *f_iter);
+
+        // if we're using WCF, add the corresponding attributes
+        if (wcf_) {
+                indent(f_service_) <<
+                        "[OperationContract]" << endl;
+
+                const std::vector<t_field*>& xceptions = (*f_iter)->get_xceptions()->get_members();
+                vector<t_field*>::const_iterator x_iter;
+                for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
+                  indent(f_service_) << "[FaultContract(typeof(" + type_name((*x_iter)->get_type(), false, false) + "Fault))]" << endl;
+                }
+        }
 
     indent(f_service_) <<
       function_signature(*f_iter) << ";" << endl;
     f_service_ << ");" << endl;
     scope_down(f_service_);
     f_service_ << endl;
-       
+        
     // End
     indent(f_service_) <<
       "public " << function_signature_async_end(*f_iter, "End_") << endl;
     bool first;
     if( async_||async_ctp_) {
       indent(f_service_) <<
-       "public async " << function_signature_async(*f_iter, "") << endl;
+        "public async " << function_signature_async(*f_iter, "") << endl;
       scope_up(f_service_);
       
       if (!(*f_iter)->get_returntype()->is_void()) {
         indent(f_service_);
       }
       if (async_) {
-       f_service_ << "await Task.Run(() =>" << endl;
+        f_service_ << "await Task.Run(() =>" << endl;
       } else {
-       f_service_ << "await TaskEx.Run(() =>" << endl;
+        f_service_ << "await TaskEx.Run(() =>" << endl;
       }
       scope_up(f_service_);
       indent(f_service_);
       }
       f_service_ << 
         funname << "(";
-         first = true;
+          first = true;
       for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
         if (first) {
           first = false;
         indent(f_service_) << 
           "return retval;"  << endl;
       }
-         scope_down(f_service_);
+          scope_down(f_service_);
       f_service_ << endl;
     }
     
         indent() << "iprot_.ReadMessageEnd();" << endl;
 
       if (!(*f_iter)->get_returntype()->is_void()) {
-       if (nullable_) {
-         if (type_can_be_null((*f_iter)->get_returntype())) {
-           f_service_ <<
-             indent() << "if (result.Success != null) {" << endl <<
-             indent() << "  return result.Success;" << endl <<
-             indent() << "}" << endl;
-         } else {
-           f_service_ <<
-             indent() << "if (result.Success.HasValue) {" << endl <<
-             indent() << "  return result.Success.Value;" << endl <<
-             indent() << "}" << endl;
-         }
-       } else {
-         f_service_ <<
-           indent() << "if (result.__isset.success) {" << endl <<
-           indent() << "  return result.Success;" << endl <<
-           indent() << "}" << endl;
-       }
+        if (nullable_) {
+          if (type_can_be_null((*f_iter)->get_returntype())) {
+            f_service_ <<
+              indent() << "if (result.Success != null) {" << endl <<
+              indent() << "  return result.Success;" << endl <<
+              indent() << "}" << endl;
+          } else {
+            f_service_ <<
+              indent() << "if (result.Success.HasValue) {" << endl <<
+              indent() << "  return result.Success.Value;" << endl <<
+              indent() << "}" << endl;
+          }
+        } else {
+          f_service_ <<
+            indent() << "if (result.__isset.success) {" << endl <<
+            indent() << "  return result.Success;" << endl <<
+            indent() << "}" << endl;
+        }
       }
 
       t_struct *xs = (*f_iter)->get_xceptions();
       const std::vector<t_field*>& xceptions = xs->get_members();
       vector<t_field*>::const_iterator x_iter;
       for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-       if (nullable_) {
-         f_service_ <<
-           indent() << "if (result." << prop_name(*x_iter) << " != null) {" << endl <<
-           indent() << "  throw result." << prop_name(*x_iter) << ";" << endl <<
-           indent() << "}" << endl;
-       } else {
-         f_service_ <<
-           indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << endl <<
-           indent() << "  throw result." << prop_name(*x_iter) << ";" << endl <<
-           indent() << "}" << endl;
-       }
+        if (nullable_) {
+          f_service_ <<
+            indent() << "if (result." << prop_name(*x_iter) << " != null) {" << endl <<
+            indent() << "  throw result." << prop_name(*x_iter) << ";" << endl <<
+            indent() << "}" << endl;
+        } else {
+          f_service_ <<
+            indent() << "if (result.__isset." << (*x_iter)->get_name() << ") {" << endl <<
+            indent() << "  throw result." << prop_name(*x_iter) << ";" << endl <<
+            indent() << "}" << endl;
+        }
       }
 
       if ((*f_iter)->get_returntype()->is_void()) {
                   << " " << prop_name(tfield) << " { get; set; }" << endl;
     } else {
       indent(out) << (isPublic ? "public " : "private ") << type_name(tfield->get_type(), false, false, true)
-                 << " " << prop_name(tfield) << endl;
+                  << " " << prop_name(tfield) << endl;
       scope_up(out);
       indent(out) << "get" << endl;
       scope_up(out);
       bool use_nullable = false;
       if (nullable_) {
-       t_type* ttype = tfield->get_type();
-       while (ttype->is_typedef()) {
-         ttype = ((t_typedef*)ttype)->get_type();
-       }
-       if (ttype->is_base_type()) {
-         use_nullable = ((t_base_type*)ttype)->get_base() != t_base_type::TYPE_STRING;
-       }
+        t_type* ttype = tfield->get_type();
+        while (ttype->is_typedef()) {
+          ttype = ((t_typedef*)ttype)->get_type();
+        }
+        if (ttype->is_base_type()) {
+          use_nullable = ((t_base_type*)ttype)->get_base() != t_base_type::TYPE_STRING;
+        }
       }
       indent(out) << "return " << fieldPrefix + tfield->get_name() << ";" << endl;
       scope_down(out);
       indent(out) << "set" << endl;
       scope_up(out);
       if (use_nullable) {
-       if (generateIsset) {
-         indent(out) << "__isset." << tfield->get_name() << " = value.HasValue;" << endl;
-       }
-       indent(out) << "if (value.HasValue) this." << fieldPrefix + tfield->get_name() << " = value.Value;" << endl;
+        if (generateIsset) {
+          indent(out) << "__isset." << tfield->get_name() << " = value.HasValue;" << endl;
+        }
+        indent(out) << "if (value.HasValue) this." << fieldPrefix + tfield->get_name() << " = value.Value;" << endl;
       } else {
-       if (generateIsset) {
-         indent(out) << "__isset." << tfield->get_name() << " = true;" << endl;
-       }
-       indent(out) << "this." << fieldPrefix + tfield->get_name() << " = value;" << endl;
+        if (generateIsset) {
+          indent(out) << "__isset." << tfield->get_name() << " = true;" << endl;
+        }
+        indent(out) << "this." << fieldPrefix + tfield->get_name() << " = value;" << endl;
       }
       scope_down(out);
       scope_down(out);
 
 void t_csharp_generator::generate_csharp_doc(ofstream &out, t_function* tfunction) {
   if (tfunction->has_doc()) {
-       stringstream ps;
+        stringstream ps;
     const vector<t_field*>& fields = tfunction->get_arglist()->get_members();
     vector<t_field*>::const_iterator p_iter;
     for (p_iter = fields.begin(); p_iter != fields.end(); ++p_iter) {
       t_field* p = *p_iter;
       ps << "\n<param name=\"" << p->get_name() << "\">";
       if (p->has_doc()) {
-               std::string str = p->get_doc();
-               str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); // remove the newlines that appear from the parser
-               ps << str;
+                std::string str = p->get_doc();
+                str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); // remove the newlines that appear from the parser
+                ps << str;
       }
-         ps << "</param>";
+          ps << "</param>";
     }
     generate_docstring_comment(out,
                                "",
                                "/// ",
-                                                          "<summary>\n" + tfunction->get_doc() + "</summary>" + ps.str(),
+                                                           "<summary>\n" + tfunction->get_doc() + "</summary>" + ps.str(),
                                "");
   }
 }