public override void DeclareTypes(CsCodeWriter code) { string collection = GetStorageType(code); string itemType = _generator.GetPublicType(code); using (code.CodeRegion(collection)) using (code.DeclareClass( new CodeItem(collection) { Access = FieldAccess.Private }, new[] { CsCodeWriter.Global + "System.Collections.Generic.IList<" + _generator.GetPublicType(code) + ">", CsCodeWriter.Global + "System.ICloneable", })) { using(code.WriteBlock("private static T AssertNotNull<T>(T value) where T : class")) { code.WriteLine("if (null == value) throw new {0}System.ArgumentNullException({1});", CsCodeWriter.Global, code.MakeString(PropertyName)); code.WriteLine("return value;"); } string value = _generator.IsNullable ? "AssertNotNull(value)" : "value"; code.WriteLine("private bool _readOnly;"); code.WriteLine("private readonly {0}System.Collections.Generic.List<{1}> _contents;", CsCodeWriter.Global, itemType); using(code.WriteBlock("public {0}()", collection)) { code.WriteLine("_readOnly = false;"); code.WriteLine("_contents = new {0}System.Collections.Generic.List<{1}>();", CsCodeWriter.Global, itemType); } using (code.WriteBlock("public {0}({1}System.Collections.Generic.IList<{2}> contents, bool clone)", collection, CsCodeWriter.Global, itemType)) { code.WriteLine("_readOnly = false;"); if (!_generator.IsNullable) { code.WriteLine("_contents = new {0}System.Collections.Generic.List<{1}>(AssertNotNull(contents));", CsCodeWriter.Global, itemType); } else { code.WriteLine("_contents = new {0}System.Collections.Generic.List<{1}>(AssertNotNull(contents).Count);", CsCodeWriter.Global, itemType); using (code.WriteBlock("foreach ({0} item in contents)", _generator.GetPublicType(code))) { if (_generator.IsMessage) { code.WriteLine("if (clone)"); code.WriteLineIndent("_contents.Add(({0})AssertNotNull(item).Clone());", itemType); code.WriteLine("else"); } code.WriteLine("_contents.Add(AssertNotNull(item));"); } } } _generator.Constraints.ForAll(x => x.WriteMember(code)); using (code.WriteBlock("public void MakeReadOnly()")) { code.WriteLine("if (_readOnly) return;"); code.WriteLine("_readOnly = true;"); if (_generator.IsMessage) using (code.WriteBlock("for (int i=0; i < _contents.Count; i++)")) { _generator.MakeReadOnly(code, "_contents[i]"); } } using (code.WriteBlock("private {0}System.Collections.Generic.List<{1}> Modify", CsCodeWriter.Global, itemType)) code.WriteLine("get {{ if (!IsReadOnly) return _contents; throw new {0}System.InvalidOperationException(); }}", CsCodeWriter.Global); using (code.WriteBlock("public {0} this[int index]", itemType)) { code.WriteLine("get { return _contents[index]; }"); code.WriteLine("set {{ Modify[index] = {0}; }}", value); } code.WriteLine("public int Count { get { return _contents.Count; } }"); code.WriteLine("public bool IsReadOnly { get { return _readOnly; } }"); code.WriteLine("public void Add({0} value) {{ Modify.Add({1}); }}", itemType, value); using (code.WriteBlock("public void AddRange({1}System.Collections.Generic.ICollection<{0}> value)", itemType, CsCodeWriter.Global)) { if (_generator.IsNullable) code.WriteLine("foreach ({0} item in AssertNotNull(value)) AssertNotNull(item);", _generator.GetPublicType(code)); code.WriteLine("Modify.AddRange(AssertNotNull(value));"); } code.WriteLine("public void Insert(int index, {0} value) {{ Modify.Insert(index, {1}); }}", itemType, value); code.WriteLine("public bool Remove({0} item) {{ return Modify.Remove(item); }}", itemType); code.WriteLine("public void RemoveAt(int index) { Modify.RemoveAt(index); }"); code.WriteLine("public void Clear() { Modify.Clear(); }"); code.WriteLine("public bool Contains({0} item) {{ return _contents.Contains(item); }}", itemType); code.WriteLine("public int IndexOf({0} item) {{ return _contents.IndexOf(item); }}", itemType); code.WriteLine("public void CopyTo({0}[] array, int arrayIndex) {{ _contents.CopyTo(array, arrayIndex); }}", itemType); code.WriteLine("object {0}System.ICloneable.Clone() {{ return Clone(); }}", CsCodeWriter.Global); using (code.WriteBlock("public {0} Clone()", collection)) { code.WriteLine("return _readOnly ? this : new {0}(this, true);", collection); } code.WriteLine("public {0}System.Collections.Generic.IEnumerator<{1}> GetEnumerator()", CsCodeWriter.Global, itemType); code.WriteLine("{ return _contents.GetEnumerator(); }"); code.WriteLine("{0}System.Collections.IEnumerator {0}System.Collections.IEnumerable.GetEnumerator()", CsCodeWriter.Global); code.WriteLine("{{ return (({0}System.Collections.IEnumerable)_contents).GetEnumerator(); }}", CsCodeWriter.Global); } }