This is an follow up discussion on the previous impl of the c# - design of generic version of interface with its non generic verion. In this example, I will introduce a more real world like example (however, stil this code need to be improved).
First is the declarations of the interfaces.
// boqwang: [placeholder] // better to call "Duplexer"? interface IProfilePersistenceProxy { void HookPersistenceEvent(IPersistableStateOwner stateOwner); } interface IProfilePersistenceProxy<T> : IProfilePersistenceProxy { void HookPersistenceEvent(IPersistableEnumerableStateOwner<T> stateOwner); }
and below is class definition
// boqwang: [placeholder] class RamboProfilePersistenceProxy : // boqwang - IProfilePersistenceProxy { protected internal WpfApplicationPersistence persistence; public RamboProfilePersistenceProxy( WpfApplicationPersistence appPersistence ) { this.persistence = appPersistence; } public virtual void HookPersistenceEvent(IPersistableStateOwner stateOwner) { // boqwang - Q? // is it possible to determine if a if (stateOwner == null) throw new ArgumentNullException("stateOwner"); Trace.WriteLine("RamboProfilePersistenceProxy"); Type type = stateOwner.GetType(); if (type.GetGenericTypeDefinition() == typeof(IPersistableEnumerableStateOwner<>)) { // .... } throw new NotImplementedException(); } } class RamboProfilePersistenceProxy<T> : RamboProfilePersistenceProxy, IProfilePersistenceProxy<T>, IProfilePersistenceProxy { public RamboProfilePersistenceProxy( WpfApplicationPersistence appPersistence ) : base(appPersistence) { } public override void HookPersistenceEvent(IPersistableStateOwner stateOwner) { Trace.WriteLine("RamboProfilePersistenceProxy<T>"); if (stateOwner is IPersistableEnumerableStateOwner<T>) { HookPersistenceEvent((IPersistableEnumerableStateOwner<T>) stateOwner); } else { base.HookPersistenceEvent(stateOwner); } } void IProfilePersistenceProxy.HookPersistenceEvent(IPersistableStateOwner stateOwner) { this.HookPersistenceEvent(stateOwner); } public void HookPersistenceEvent(IPersistableEnumerableStateOwner<T> stateOwner) { if (stateOwner == null) throw new ArgumentNullException("stateOwner"); stateOwner.StateSaving += new EventHandler<PersistableEnumerableStateSavingEventArgs<T>>(stateOwner_StateSaving); stateOwner.StateLoaded += new EventHandler<PersistableEnumerableStateLoadedEventArgs<T>>(stateOwner_StateLoaded); if (persistableStateOwners.FirstOrDefault(p => p.GetType() == stateOwner.GetType()) == null) { persistableStateOwners.Add(stateOwner); } // - boqwang: silently/quitely/noiselessly/soundlessly/stillnessly ignore. } List<IPersistableStateOwner> persistableStateOwners = new List<IPersistableStateOwner>(); void stateOwner_StateLoaded<T>(object sender, PersistableEnumerableStateLoadedEventArgs<T> e) { throw new NotImplementedException(); } void stateOwner_StateSaving<T>(object sender, PersistableEnumerableStateSavingEventArgs<T> e) { throw new NotImplementedException(); } }
The things that I wantted to highlight here is that the Generic class has impl both the the generic interface and the non-generic interface, also it tries to override the interfaces that is inherited from its base classs, a non-generic class.