using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using IjwFramework.Collections; namespace OpenRa.FileFormats { public class TypeDictionary { Cache> innerInherit = new Cache>( _ => new List() ); public void Add( object val ) { var t = val.GetType(); foreach( var i in t.GetInterfaces() ) innerInherit[ i ].Add( val ); foreach( var tt in t.BaseTypes() ) innerInherit[ tt ].Add( val ); } public bool Contains() { return innerInherit[ typeof( T ) ].Count != 0; } public T Get() { var l = innerInherit[ typeof( T ) ]; if( l.Count == 1 ) return (T)l[ 0 ]; else if( l.Count == 0 ) throw new InvalidOperationException( string.Format( "TypeDictionary does not contain instance of type `{0}`", typeof( T ) ) ); else throw new InvalidOperationException( string.Format( "TypeDictionary contains multiple instance of type `{0}`", typeof( T ) ) ); } public T GetOrDefault() { var l = innerInherit[ typeof( T ) ]; if( l.Count == 1 ) return (T)l[ 0 ]; else if( l.Count == 0 ) return default( T ); else throw new InvalidOperationException( string.Format( "TypeDictionary contains multiple instance of type `{0}`", typeof( T ) ) ); } public IEnumerable WithInterface() { foreach( var i in innerInherit[ typeof( T ) ] ) yield return (T)i; } public IEnumerator GetEnumerator() { return WithInterface().GetEnumerator(); } } static class TypeExts { public static IEnumerable BaseTypes( this Type t ) { while( t != null ) { yield return t; t = t.BaseType; } } } }