Fixing an issue with output parameters that are of type IntPtr
[castle.git] / MonoRail / Castle.MonoRail.Framework.Tests / Helpers / FormHelperTestCase.cs
blob46b579ff928df829753800a706146dc76bed63f7
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.MonoRail.Framework.Tests.Helpers
17 using System;
18 using System.Collections;
19 using System.Collections.Generic;
20 using System.Collections.Specialized;
21 using System.Globalization;
22 using System.IO;
23 using System.Reflection;
24 using System.Threading;
25 using Castle.Core.Interceptor;
26 using Castle.DynamicProxy;
27 using Castle.MonoRail.Framework.Helpers;
28 using Castle.MonoRail.Framework.Tests.Controllers;
29 using NUnit.Framework;
31 [TestFixture]
32 public class FormHelperTestCase
34 private FormHelper helper;
35 private Product product;
36 private SimpleUser user;
37 private Subscription subscription;
38 private Month[] months;
40 [SetUp]
41 public void Init()
43 CultureInfo en = CultureInfo.CreateSpecificCulture("en");
45 Thread.CurrentThread.CurrentCulture = en;
46 Thread.CurrentThread.CurrentUICulture = en;
48 helper = new FormHelper();
50 subscription = new Subscription();
51 months = new Month[] { new Month(1, "January"), new Month(1, "February") };
52 product = new Product("memory card", 10, (decimal)12.30);
54 user = new SimpleUser();
56 HomeController controller = new HomeController();
57 ControllerContext context = new ControllerContext();
59 context.PropertyBag.Add("product", product);
60 context.PropertyBag.Add("user", user);
61 context.PropertyBag.Add("roles", new Role[] { new Role(1, "a"), new Role(2, "b"), new Role(3, "c") });
62 context.PropertyBag.Add("sendemail", true);
63 context.PropertyBag.Add("sendemailstringtrue", "true");
64 context.PropertyBag.Add("sendemailstringfalse", "false");
65 context.PropertyBag.Add("confirmation", "abc");
66 context.PropertyBag.Add("fileaccess", FileAccess.Read);
67 context.PropertyBag.Add("subscription", subscription);
68 context.PropertyBag.Add("months", months);
70 helper.SetController(controller, context);
73 [Test]
74 public void FormTagDoesNotMixUrlParametersWithFormElementParameters()
76 // No solution here. Id is ambiguous
77 // helper.FormTag(DictHelper.Create("noaction=true"));
80 [Test]
81 public void OverridingElementId()
83 Assert.AreEqual("<input type=\"text\" id=\"something\" name=\"product.name\" value=\"memory card\" />",
84 helper.TextField("product.name", DictHelper.Create("id=something")));
86 Assert.AreEqual("<input type=\"password\" id=\"something\" name=\"product.name\" value=\"memory card\" />",
87 helper.PasswordField("product.name", DictHelper.Create("id=something")));
89 Assert.AreEqual("<input type=\"hidden\" id=\"something\" name=\"product.name\" value=\"memory card\" />",
90 helper.HiddenField("product.name", DictHelper.Create("id=something")));
92 product.IsAvailable = false;
94 Assert.AreEqual("<input type=\"checkbox\" id=\"something\" name=\"product.isavailable\" value=\"true\" />" +
95 "<input type=\"hidden\" id=\"somethingH\" name=\"product.isavailable\" value=\"false\" />",
96 helper.CheckboxField("product.isavailable", DictHelper.Create("id=something")));
98 user.IsActive = true;
100 Assert.AreEqual(
101 "<input type=\"radio\" id=\"something\" name=\"user.isactive\" value=\"True\" checked=\"checked\" />",
102 helper.RadioField("user.isactive", true, DictHelper.Create("id=something")));
104 Assert.AreEqual("<label for=\"something\">Name:</label>",
105 helper.LabelFor("product.name", "Name:", DictHelper.Create("id=something")));
107 ArrayList list = new ArrayList();
109 list.Add("cat1");
110 list.Add("cat2");
112 Assert.AreEqual("<select id=\"something\" name=\"product.category.id\" >" + Environment.NewLine +
113 "<option value=\"cat1\">cat1</option>" + Environment.NewLine + "<option value=\"cat2\">cat2</option>" +
114 Environment.NewLine + "</select>",
115 helper.Select("product.category.id", list, DictHelper.Create("id=something")));
118 [Test]
119 public void TextField()
121 Assert.AreEqual("<input type=\"text\" id=\"product_name\" name=\"product.name\" value=\"memory card\" />",
122 helper.TextField("product.name"));
123 Assert.AreEqual("<input type=\"text\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" />",
124 helper.TextField("product.quantity"));
127 [Test]
128 public void TextFieldWithAutoCompletion()
130 Assert.AreEqual("<input type=\"text\" id=\"product_name\" name=\"product.name\" value=\"memory card\" autocomplete=\"off\" /><div id=\"product_nameautocomplete\" class=\"auto_complete\"></div><script type=\"text/javascript\">new Ajax.Autocompleter('product_name', 'product_nameautocomplete', 'someurl',{})</script>",
131 helper.TextFieldAutoComplete("product.name", "someurl", DictHelper.Create(), DictHelper.Create()));
132 Assert.AreEqual("<input type=\"text\" id=\"product_name\" name=\"product.name\" value=\"memory card\" autocomplete=\"on\" /><div id=\"product_nameautocomplete\" class=\"auto_complete\"></div><script type=\"text/javascript\">new Ajax.Autocompleter('product_name', 'product_nameautocomplete', 'someurl',{})</script>",
133 helper.TextFieldAutoComplete("product.name", "someurl", DictHelper.Create("autocomplete=on"), DictHelper.Create()));
134 Assert.IsTrue(helper.TextFieldAutoComplete("product.name", "someurl", DictHelper.Create(), DictHelper.Create()).Contains(helper.TextField("product.name", DictHelper.Create("autocomplete=off"))));
137 [Test]
138 public void NumberField()
140 Assert.AreEqual(
141 "<input type=\"text\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" onkeypress=\"return monorail_formhelper_numberonly(event, [], []);\" />",
142 helper.NumberField("product.quantity"));
143 Assert.AreEqual(
144 "<input type=\"text\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" onkeypress=\"return monorail_formhelper_numberonly(event, [1], []);\" />",
145 helper.NumberField("product.quantity", DictHelper.Create("exceptions=1")));
146 Assert.AreEqual(
147 "<input type=\"text\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" onkeypress=\"return monorail_formhelper_numberonly(event, [1,2], []);\" />",
148 helper.NumberField("product.quantity", DictHelper.Create("exceptions=1,2")));
151 [Test]
152 public void MaskedNumberField()
154 Assert.AreEqual(
155 "<input type=\"text\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" onkeypress=\"return monorail_formhelper_numberonly(event, [], []);\" " +
156 "onblur=\"javascript:void(0);return monorail_formhelper_mask(event,this,'2,5','-');\" onkeyup=\"javascript:void(0);return monorail_formhelper_mask(event,this,'2,5','-');\" />",
157 helper.NumberField("product.quantity", DictHelper.Create("mask=2,5")));
160 [Test]
161 public void PasswordField()
163 Assert.AreEqual("<input type=\"password\" id=\"product_name\" name=\"product.name\" value=\"memory card\" />",
164 helper.PasswordField("product.name"));
165 Assert.AreEqual("<input type=\"password\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" />",
166 helper.PasswordField("product.quantity"));
167 Assert.AreEqual("<input type=\"password\" id=\"confirmation\" name=\"confirmation\" value=\"abc\" />",
168 helper.PasswordField("confirmation"));
171 [Test]
172 public void TextFieldValue()
174 Assert.AreEqual("<input type=\"text\" id=\"product_price\" name=\"product.price\" value=\"$12.30\" />",
175 helper.TextFieldValue("product.price", product.Price.ToString("C")));
178 [Test]
179 public void TextFieldFormat()
181 Assert.AreEqual("<input type=\"text\" id=\"product_price\" name=\"product.price\" value=\"$12.30\" />",
182 helper.TextField("product.price", DictHelper.Create("textformat=C")));
185 [Test]
186 public void HiddenField()
188 Assert.AreEqual("<input type=\"hidden\" id=\"product_name\" name=\"product.name\" value=\"memory card\" />",
189 helper.HiddenField("product.name"));
190 Assert.AreEqual("<input type=\"hidden\" id=\"product_quantity\" name=\"product.quantity\" value=\"10\" />",
191 helper.HiddenField("product.quantity"));
194 [Test]
195 public void CheckboxField()
197 product.IsAvailable = false;
199 Assert.AreEqual(
200 "<input type=\"checkbox\" id=\"product_isavailable\" name=\"product.isavailable\" value=\"true\" />" +
201 "<input type=\"hidden\" id=\"product_isavailableH\" name=\"product.isavailable\" value=\"false\" />",
202 helper.CheckboxField("product.isavailable"));
204 product.IsAvailable = true;
206 Assert.AreEqual(
207 "<input type=\"checkbox\" id=\"product_isavailable\" name=\"product.isavailable\" value=\"true\" checked=\"checked\" />" +
208 "<input type=\"hidden\" id=\"product_isavailableH\" name=\"product.isavailable\" value=\"false\" />",
209 helper.CheckboxField("product.isavailable"));
211 Assert.AreEqual(
212 "<input type=\"checkbox\" id=\"sendemail\" name=\"sendemail\" value=\"true\" checked=\"checked\" />" +
213 "<input type=\"hidden\" id=\"sendemailH\" name=\"sendemail\" value=\"false\" />",
214 helper.CheckboxField("sendemail"));
216 Assert.AreEqual(
217 "<input type=\"checkbox\" id=\"sendemail\" name=\"sendemail\" value=\"true\" checked=\"checked\" />" +
218 "<input type=\"hidden\" id=\"sendemailH\" name=\"sendemail\" value=\"0\" />",
219 helper.CheckboxField("sendemail", new DictHelper().CreateDict("falseValue=0")));
221 // Checkbox values are actually added as string values to the Flash
222 // NameValueCollection of the Controller. Therefore a string "false"
223 // must render an unchecked checkbox.
224 Assert.AreEqual("<input type=\"checkbox\" id=\"sendemailstringtrue\" name=\"sendemailstringtrue\" value=\"true\" checked=\"checked\" />" +
225 "<input type=\"hidden\" id=\"sendemailstringtrueH\" name=\"sendemailstringtrue\" value=\"false\" />",
226 helper.CheckboxField("sendemailstringtrue"));
228 Assert.AreEqual("<input type=\"checkbox\" id=\"sendemailstringfalse\" name=\"sendemailstringfalse\" value=\"true\" />" +
229 "<input type=\"hidden\" id=\"sendemailstringfalseH\" name=\"sendemailstringfalse\" value=\"false\" />",
230 helper.CheckboxField("sendemailstringfalse"));
234 [Test]
235 public void RadioField()
237 user.IsActive = true;
239 Assert.AreEqual(
240 "<input type=\"radio\" id=\"user_isactive\" name=\"user.isactive\" value=\"True\" checked=\"checked\" />",
241 helper.RadioField("user.isactive", true));
243 user.IsActive = false;
245 Assert.AreEqual("<input type=\"radio\" id=\"user_isactive\" name=\"user.isactive\" value=\"True\" />",
246 helper.RadioField("user.isactive", true));
249 [Test]
250 public void RadioFieldWithEnums()
252 Assert.AreEqual("<input type=\"radio\" id=\"fileaccess\" name=\"fileaccess\" value=\"Read\" checked=\"checked\" />",
253 helper.RadioField("fileaccess", FileAccess.Read));
255 Assert.AreEqual("<input type=\"radio\" id=\"fileaccess\" name=\"fileaccess\" value=\"Read\" checked=\"checked\" />",
256 helper.RadioField("fileaccess", "Read"));
258 Assert.AreEqual("<input type=\"radio\" id=\"fileaccess\" name=\"fileaccess\" value=\"Write\" />",
259 helper.RadioField("fileaccess", FileAccess.Write));
261 Assert.AreEqual("<input type=\"radio\" id=\"fileaccess\" name=\"fileaccess\" value=\"Write\" />",
262 helper.RadioField("fileaccess", "Write"));
265 [Test]
266 public void LabelFor()
268 Assert.AreEqual("<label for=\"product_name\">Name:</label>",
269 helper.LabelFor("product.name", "Name:"));
272 [Test]
273 public void LabelForAttributed()
275 IDictionary attrs = new ListDictionary();
276 attrs.Add("class", "cssclass");
277 Assert.AreEqual("<label for=\"product_name\" class=\"cssclass\" >Name:</label>",
278 helper.LabelFor("product.name", "Name:", attrs));
281 [Test]
282 public void TextFieldWithIndex()
284 Assert.AreEqual("<input type=\"text\" id=\"roles_0_Id\" name=\"roles[0].Id\" value=\"1\" />",
285 helper.TextField("roles[0].Id"));
287 Assert.AreEqual("<input type=\"text\" id=\"roles_1_Name\" name=\"roles[1].Name\" value=\"b\" />",
288 helper.TextField("roles[1].Name"));
291 [Test]
292 public void TextFieldWithNestedIndex()
294 user.Roles.Add(new Role(1, "role1"));
295 user.Roles.Add(new Role(2, "role2"));
297 Assert.AreEqual("<input type=\"text\" id=\"user_roles_0_Id\" name=\"user.roles[0].Id\" value=\"1\" />",
298 helper.TextField("user.roles[0].Id"));
300 Assert.AreEqual("<input type=\"text\" id=\"user_roles_0_Name\" name=\"user.roles[0].Name\" value=\"role1\" />",
301 helper.TextField("user.roles[0].Name"));
303 Assert.AreEqual("<input type=\"text\" id=\"user_roles_1_Name\" name=\"user.roles[1].Name\" value=\"role2\" />",
304 helper.TextField("user.roles[1].Name"));
307 [Test]
308 public void TextFieldWithNestedIndexAndNullValues1()
310 user.Roles = null;
312 Assert.AreEqual("<input type=\"text\" id=\"user_roles_0_Id\" name=\"user.roles[0].Id\" value=\"\" />",
313 helper.TextField("user.roles[0].Id"));
315 Assert.AreEqual("<input type=\"text\" id=\"user_roles_0_Name\" name=\"user.roles[0].Name\" value=\"\" />",
316 helper.TextField("user.roles[0].Name"));
318 Assert.AreEqual("<input type=\"text\" id=\"user_roles_1_Name\" name=\"user.roles[1].Name\" value=\"\" />",
319 helper.TextField("user.roles[1].Name"));
322 [Test]
323 public void TextFieldWithNestedIndexAndNullValues2()
325 user.Roles.Add(new Role(1, null));
326 user.Roles.Add(new Role(2, null));
328 Assert.AreEqual("<input type=\"text\" id=\"user_roles_0_Name\" name=\"user.roles[0].Name\" value=\"\" />",
329 helper.TextField("user.roles[0].Name"));
331 Assert.AreEqual("<input type=\"text\" id=\"user_roles_1_Name\" name=\"user.roles[1].Name\" value=\"\" />",
332 helper.TextField("user.roles[1].Name"));
335 [Test]
336 public void IndexedValueTextFieldInDotNet2()
338 subscription.Months4.Clear();
339 subscription.Months4.Add(new Month(1, "Jan"));
340 subscription.Months4.Add(new Month(2, "Feb"));
342 Assert.AreEqual(
343 "<input type=\"text\" id=\"subscription_months4_0_id\" name=\"subscription.months4[0].id\" value=\"1\" />",
344 helper.TextField("subscription.months4[0].id"));
345 Assert.AreEqual(
346 "<input type=\"text\" id=\"subscription_months4_0_name\" name=\"subscription.months4[0].name\" value=\"Jan\" />",
347 helper.TextField("subscription.months4[0].name"));
350 [Test, ExpectedException(typeof(MonoRailException))]
351 public void InvalidIndex1()
353 helper.TextField("roles[a].Id");
356 [Test, ExpectedException(typeof(MonoRailException))]
357 public void InvalidIndex2()
359 helper.TextField("roles[1a].Id");
362 [Test, ExpectedException(typeof(MonoRailException)), Ignore("The behavior for array access has changed")]
363 public void InvalidIndex3()
365 helper.TextField("roles[10].Id");
368 [Test]
369 public void ShouldDiscoverRootTypeOnCollectionWhenIndexedRootInPropertyBag()
371 FormHelperEx sut = new FormHelperEx();
372 sut.SetController(new HomeController(), new ControllerContext());
374 //this is what current code requires to discover
375 sut.ControllerContext.PropertyBag["items[0]type"] = typeof(Product);
376 PropertyInfo prop = sut.ObtainTargetProperty(RequestContext.PropertyBag, "items[0].Name");
377 PropertyInfo expect = typeof(Product).GetProperty("Name");
378 Assert.AreEqual(expect, prop);
381 [Test]
382 public void ShouldDiscoverRootTypeOnCollection()
384 FormHelperEx sut = new FormHelperEx();
385 sut.SetController(new HomeController(), new ControllerContext());
387 sut.ControllerContext.PropertyBag["itemstype"] = typeof(Product); //no need to pass indexer
388 PropertyInfo prop = sut.ObtainTargetProperty(RequestContext.PropertyBag, "items[0].Name");
389 PropertyInfo expect = typeof(Product).GetProperty("Name");
390 Assert.AreEqual(expect, prop);
393 [Test]
394 public void ShouldFailToDiscoverRootTypeOnCollectionWhenNoTypeInPropertyBag()
396 FormHelperEx sut = new FormHelperEx();
397 sut.SetController(new HomeController(), new ControllerContext());
399 PropertyInfo prop = sut.ObtainTargetProperty(RequestContext.PropertyBag, "items[0].Name");
400 Assert.IsNull(prop);
403 [Test]
404 public void TargetValueCanBeObtainedForOverridenProperties()
406 helper.ControllerContext.PropertyBag["december"] = new December();
407 helper.TextField("december.Name");
410 // [Test]
411 // public void TargetValueCanBeObtainedForOverridenProxiedProperties()
412 // {
413 // ProxyGenerator generator = new ProxyGenerator();
414 // object proxy = generator.CreateClassProxy(typeof(Month), new StandardInterceptor(), 12, "December");
415 // helper.ControllerContext.PropertyBag["december"] = proxy;
416 // helper.TextField("december.Name");
417 // }
419 [Test]
420 public void TargetValueCanBeObtainedForOverridenGenericProperties()
422 ClassThatOverridesGenericProperty mr424 = new ClassThatOverridesGenericProperty();
423 helper.ControllerContext.PropertyBag.Add("mr424", mr424);
425 mr424.Prop = null;
426 Assert.AreEqual("<input type=\"text\" id=\"mr424_prop\" name=\"mr424.prop\" value=\"(unknown)\" />",
427 helper.TextField("mr424.prop"));
429 mr424.Prop = "propvalue";
430 Assert.AreEqual("<input type=\"text\" id=\"mr424_prop\" name=\"mr424.prop\" value=\"propvalue\" />",
431 helper.TextField("mr424.prop"));
434 public class FormHelperEx : FormHelper
436 public PropertyInfo ObtainTargetProperty(RequestContext context, string target)
438 return ObtainTargetProperty(context, target, null);
444 #region Classes skeletons
446 public class BaseClassWithGenericProperty<T>
448 private T prop;
450 public virtual T Prop
452 get { return prop; }
453 set { prop = value; }
457 public class ClassThatOverridesGenericProperty : BaseClassWithGenericProperty<string>
459 public override string Prop
461 get { return base.Prop ?? "(unknown)"; }
462 set { base.Prop = value; }
465 public class Month
467 private int id;
468 private String name;
470 public Month(int id, string name)
472 this.id = id;
473 this.name = name;
476 public virtual int Id
478 get { return id; }
479 set { id = value; }
482 public virtual string Name
484 get { return name; }
485 set { name = value; }
489 // public class NullInterceptor : IInterceptor
490 // {
491 // public object Intercept(IInvocation invocation, params object[] args)
492 // {
493 // return invocation.Proceed(args);
494 // }
495 // }
497 public class December : Month
499 public December() : base(12, "December")
503 public override string Name
505 get { return base.Name; }
506 set { throw new InvalidOperationException(); }
510 public class Subscription
512 private int[] months;
513 private IList months2 = new ArrayList();
514 private Month[] months3;
515 private IList<Month> months4 = new CustomList<Month>();
517 public int[] Months
519 get { return months; }
520 set { months = value; }
523 public IList Months2
525 get { return months2; }
526 set { months2 = value; }
529 public Month[] Months3
531 get { return months3; }
532 set { months3 = value; }
535 public IList<Month> Months4
537 get { return months4; }
538 set { months4 = value; }
542 public class Product
544 private string name;
545 private int quantity;
546 private bool isAvailable;
547 private decimal price;
548 private ProductCategory category = new ProductCategory();
550 public Product()
554 public Product(string name, int quantity, decimal price)
556 this.name = name;
557 this.quantity = quantity;
558 this.price = price;
561 public virtual string Name
563 get { return name; }
564 set { name = value; }
567 public virtual int Quantity
569 get { return quantity; }
570 set { quantity = value; }
573 public virtual decimal Price
575 get { return price; }
576 set { price = value; }
579 public virtual bool IsAvailable
581 get { return isAvailable; }
582 set { isAvailable = value; }
585 public virtual ProductCategory Category
587 get { return category; }
588 set { category = value; }
592 public class ProductCategory
594 private int id;
595 private String name;
597 public ProductCategory()
601 public ProductCategory(int id, String name)
603 this.id = id;
604 this.name = name;
607 public virtual int Id
609 get { return id; }
610 set { id = value; }
613 public virtual String Name
615 get { return name; }
616 set { name = value; }
620 public class Role
622 private int id;
623 private String name;
625 public Role(int id, string name)
627 this.id = id;
628 this.name = name;
631 public virtual int Id
633 get { return id; }
634 set { id = value; }
637 public virtual String Name
639 get { return name; }
640 set { name = value; }
643 public override bool Equals(object obj)
645 Role other = obj as Role;
647 if (other != null)
649 return other.Id == Id;
652 return false;
655 public override int GetHashCode()
657 return id;
660 public override string ToString()
662 return name;
666 public class Role2
668 private int identification;
669 private String name;
671 public Role2(int id, string name)
673 identification = id;
674 this.name = name;
677 public virtual int Identification
679 get { return identification; }
680 set { identification = value; }
683 public virtual String Name
685 get { return name; }
686 set { name = value; }
690 public class SimpleUser
692 public enum RegistrationEnum
694 unregistered = 1,
695 pending = 2,
696 registered = 6
699 private int id;
700 private String name;
701 private ArrayList roles = new ArrayList();
702 private bool isActive;
703 private RegistrationEnum registration = RegistrationEnum.registered;
705 public SimpleUser()
709 public SimpleUser(int id, bool isActive)
711 this.id = id;
712 this.isActive = isActive;
715 public int Id
717 get { return id; }
718 set { id = value; }
721 public bool IsActive
723 get { return isActive; }
724 set { isActive = value; }
727 public string Name
729 get { return name; }
730 set { name = value; }
733 public RegistrationEnum Registration
735 get { return registration; }
736 set { registration = value; }
739 public Role[] RolesAsArray
741 get { return (Role[])roles.ToArray(typeof(Role)); }
744 public ArrayList Roles
746 get { return roles; }
747 set { roles = value; }
751 public class Contact
753 private Month dobMonth;
755 public virtual Month DobMonth
757 get { return dobMonth; }
758 set { dobMonth = value; }
762 public class CustomList<T> : IList<T>
764 readonly List<T> innerList = new List<T>();
766 public int IndexOf(T item)
768 return innerList.IndexOf(item);
771 public void Insert(int index, T item)
773 innerList.Insert(index, item);
776 public void RemoveAt(int index)
778 innerList.RemoveAt(index);
781 public T this[int index]
783 get { return innerList[index]; }
784 set { innerList[index] = value; }
787 public void Add(T item)
789 innerList.Add(item);
792 public void Clear()
794 innerList.Clear();
797 public bool Contains(T item)
799 return innerList.Contains(item);
802 public void CopyTo(T[] array, int arrayIndex)
804 throw new NotImplementedException();
807 public bool Remove(T item)
809 throw new NotImplementedException();
812 public int Count
814 get { return innerList.Count; }
817 public bool IsReadOnly
819 get { throw new NotImplementedException(); }
822 IEnumerator<T> IEnumerable<T>.GetEnumerator()
824 throw new NotImplementedException();
827 public IEnumerator GetEnumerator()
829 return innerList.GetEnumerator();
833 public interface IInterfacedList
835 int Id { get; set; }
836 string Name { get; set; }
839 public class InterfacedClassA : IInterfacedList
841 private int id;
842 private string name;
844 public InterfacedClassA(int id, string name)
846 this.id = id;
847 this.name = name;
850 #region IInterfacedList Members
852 public int Id
854 get { return id; }
855 set { id = value; }
858 public string Name
860 get { return name; }
861 set { name = value; }
864 #endregion
867 public class InterfacedClassB : IInterfacedList
869 private int id;
870 private string name;
872 public InterfacedClassB(int id, string name)
874 this.id = id;
875 this.name = name;
878 #region IInterfacedList Members
880 public int Id
882 get { return id; }
883 set { id = value; }
886 public string Name
888 get { return name; }
889 set { name = value; }
892 #endregion
895 public class Key
897 private int id;
899 public int Id
901 get { return id; }
902 set { id = value; }
905 public Key(int id)
907 this.id = id;
911 public class ClassWithCompositKey
913 private string name;
914 private Key key;
916 public ClassWithCompositKey(int id, string name)
918 this.name = name;
919 key = new Key(id);
922 public string Name
924 get { return name; }
925 set { name = value; }
928 public Key Key
930 get { return key; }
931 set { key = value; }
935 #endregion