Я собираюсь предположить, так как вы упомянули, что материал был автоматически сгенерирован, что изменение ISomeEntity находится вне окна (в противном случае я бы предложил добавить метод Display () в ISomeEntity, а затем просто вызывать его непосредственно на объекте через интерфейс. Каждый объект будет реализовывать свою собственную версию Display ()).
Итак, если я понимаю, что ваш код пытается делать правильно (это не совсем понятно), я бы предложил создать интерфейс IDisplay, наследуя от него ADisplay и BDisplay. Этот интерфейс будет иметь метод Display (), который принимает ISomeEntity и возвращает ISomeEntity. Однако, если ADisplay.Display (ISomeEntity) получает BDisplayEntity, вы бы выбросили исключение.
Затем я бы создал IDictionary, который вы бы сохранили в виде поля в классе, который имеет этот основной метод Display (я собираюсь назвать его Displayer). Этот словарь будет хранить то, что IDisplay использовать для каждого типа (то есть typeof (ADisplayEntity) -> new ADisplay ()).
Затем вы можете добавить свой основной метод Display в Displayer, но теперь сделайте так, чтобы он возвращал универсальный T, поскольку T - это тип, который вы создаете и возвращаете. Этот метод ищет, какой IDisplay ему нужен, и использует его на фабрике, созданной ISomeEntity, и результат которой возвращается.
Использование словаря означает, что вы не получите дрянную партию операторов if и что вы можете легко добавить больше IDisplays, просто добавив в словарь.
Вот мой код, который компилируется в VS2008.
public interface ISomeEntity
{
}
public class EntityFactory
{
public ISomeEntity CreateObject(string name)
{
//Do factory stuff here
return null;
}
}
public class ADisplayEntity : ISomeEntity
{
}
public class BDisplayEntity : ISomeEntity
{
}
public interface IDisplay
{
ISomeEntity Display(ISomeEntity entity);
}
public class ADisplay : IDisplay
{
public ISomeEntity Display(ISomeEntity entity)
{
ADisplayEntity aEntity = entity as ADisplayEntity;
if (aEntity == null)
throw new ArgumentException("Wrong type");
//Do whatever happens when you convert parameter entity into a
//"response" ADisplayEntity. I'm just returning a new
//ADisplayEntity to make it compile for me
return new ADisplayEntity();
}
}
public class BDisplay : IDisplay
{
public ISomeEntity Display(ISomeEntity entity)
{
BDisplayEntity bEntity = entity as BDisplayEntity;
if (bEntity == null)
throw new ArgumentException("Wrong type");
//Do whatever happens when you convert parameter entity into a
//"response" BDisplayEntity. I'm just returning a new
//BDisplayEntity to make it compile for me
return new BDisplayEntity();
}
}
public class Displayer
{
private IDictionary<Type, IDisplay> displayers;
private EntityFactory factory;
public Displayer()
{
factory = new EntityFactory();
displayers = new Dictionary<Type, IDisplay>
{
{ typeof(ADisplayEntity), new ADisplay() },
{ typeof(BDisplayEntity), new BDisplay() }
};
}
public T Display<T>() where T : class, ISomeEntity
{
T entity = factory.CreateObject((typeof(T).Name)) as T; //Type-safe because of the factory
IDisplay displayer = displayers[typeof(T)];
return displayer.Display(entity) as T; //Typesafe thanks to each IDisplay returning the correct type
}
}