GOTO OATC Wiki Home

One of the proposed things to do in our iterative development of OpenMI version 2 is to use some types of collections in the standard interfaces. One example is the ILinkableComponent interface where we have the method GetIntputExchangeItem(int index) and the property IntputExchangeItemCount. To make this feel like more object oriented the count-thing and the Get-thing should be bundled into one object (or one property of the interface). The simplest way to do this is to use e.g. the .Net type List, and with .Net version 2 such lists can be made type safe. This means that such list is in the standard defined to contain only objects of specific types (as for the GetInputExchangeItem example such list would be allowed to contain only objects of type IInputExchangeItem. However, there is another problem. If the normal type of list is used, methods such as myList.Add(object) will also be available, which we do not want for the standard.

In the two code boxes below two different possible solutions to handling lists in the standard is shown. In the first example a .Net list type called ReadOnlyCollection is used, and in the second example a new list interface is defined.

The first example has the advantage that the InputExchangeItems property will have a number of methods inherited from the .Net list. This means that e.g. constructions such as foreach can be used. The disadvantage is that it reduces the freedom for alternative implementations, only the ReadOnlyList can be used.

In the second example there is more freedom for implementation. The IIlist contains only one property and one method. The disadvantage is that constructions such as foreach cannot be used.

After playing around with these different solutions I have doubts whether it is such a good idea to change the version 1 architecture with respect the lists after all. Seems like we gain very little. We will get rid of the count properties but no real extra functionality is added and we sacrifice some freedom with respect to implementation. If we want to used list types in the standard we should used it everywhere, which also means for elementSets. Especially for elementsets it becomes clear that freedom for implementation is lost. An elementSet should be a list of elements, which will force us to define a IElement interface. In version one a IElement interface is not needed, which actually is pretty smart when implementing IElementSet for e.g. a regular 2d grid. I this case a class of type IElement never needs to be created.

public interface ILinkableComponent
    {
        ReadOnlyCollection<IInputExchangeItem> InputExchangeItems { get; }

    }

public class LCTest : ILinkableComponent
    {
        private List<IInputExchangeItem> _inputExchangeItems = new List<IInputExchangeItem>();

        public System.Collections.ObjectModel.ReadOnlyCollection<OpenMI.Standard.IInputExchangeItem> InputExchangeItems
        {
            get { return _inputExchangeItems.AsReadOnly(); }
        }
    }

class TheMainPrograme
    {
        public void test()
        {
            LCTest myModel = new LCTest();
           
            string description  = myModel.InputExchangeItems[0].Quantity.Description;
            int numberOfInputExchangeItems = myModel.InputExchangeItems.Count;

        }

    }


public interface IItems<T>
    {
        T GetItem(int index);
        int Count { get; }

    }

public interface ILinkableComponent
    {
          IItems<IInputExchangeItem> InputExchangeItems { get;}
    }

public class Items<T> : IItems<T>
    {
        private List<T> list = new List<T>();

        #region IItems<T> Members
        public T GetItem(int index)
        {
            return list[index];
        }

        public int Count
        {
            get { return list.Count; }
        }

        #endregion

        public List<T> List
        {
            get { return list; }
        }
	
    }

public class LCTest : ILinkableComponent
    {
        
        private Items<IInputExchangeItem> inputExchangeItems = new Items<IInputExchangeItem>();

        public IItems<IInputExchangeItem> InputExchangeItems
        {
            get { return ((IItems<IInputExchangeItem>) inputExchangeItems); }
        }
    
    }

class TheMainPrograme
    {
        public void test()
        {
            LCTest myModel = new LCTest();
            myModel.MyInit();

            
            description = myModel.InputExchangeItems.GetItem(0).ElementSet.Description;

            ((Items<IInputExchangeItem>)(myModel.InputExchangeItems)).List.Add(new Oatc.OpenMI.Sdk.Backbone.InputExchangeItem());
 

        }

    }